Sorting and Related Functions
Juliaは、すでにソートされた値の配列をソートし、対話するための広範で柔軟なAPIを提供しています。デフォルトでは、Juliaは合理的なアルゴリズムを選択し、昇順にソートします:
julia> sort([2,3,1])
3-element Vector{Int64}:
1
2
3逆順にソートすることもできます:
julia> sort([2,3,1], rev=true)
3-element Vector{Int64}:
3
2
1sort は、入力を変更せずにソートされたコピーを構築します。既存の配列を変更するために、ソート関数の「バン」バージョンを使用します:
julia> a = [2,3,1];
julia> sort!(a);
julia> a
3-element Vector{Int64}:
1
2
3配列を直接ソートする代わりに、配列をソートされた順序に配置するインデックスの順列を計算することができます:
julia> v = randn(5)
5-element Vector{Float64}:
0.297288
0.382396
-0.597634
-0.0104452
-0.839027
julia> p = sortperm(v)
5-element Vector{Int64}:
5
3
4
1
2
julia> v[p]
5-element Vector{Float64}:
-0.839027
-0.597634
-0.0104452
0.297288
0.382396配列は、その値の任意の変換に従ってソートすることができます:
julia> sort(v, by=abs)
5-element Vector{Float64}:
-0.0104452
0.297288
0.382396
-0.597634
-0.839027または変換によって逆の順序で:
julia> sort(v, by=abs, rev=true)
5-element Vector{Float64}:
-0.839027
-0.597634
0.382396
0.297288
-0.0104452必要に応じて、ソートアルゴリズムを選択できます:
julia> sort(v, alg=InsertionSort)
5-element Vector{Float64}:
-0.839027
-0.597634
-0.0104452
0.297288
0.382396すべてのソートおよび順序関連の関数は、操作される値に対して strict weak order を定義する「小なり」関係に依存しています。デフォルトでは isless 関数が呼び出されますが、関係は lt キーワードを介して指定できます。これは、2つの配列要素を受け取り、最初の引数が2番目の引数よりも「小さい」場合にのみ true を返す関数です。詳細については、sort! および Alternate Orderings を参照してください。
Sorting Functions
Base.sort! — Functionsort!(A; dims::Integer, alg::Base.Sort.Algorithm=Base.Sort.defalg(A), lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward)多次元配列 A を次元 dims に沿ってソートします。可能なキーワード引数の説明については、sort! の一次元バージョンを参照してください。
配列のスライスをソートするには、sortslices を参照してください。
例
julia> A = [4 3; 1 2]
2×2 Matrix{Int64}:
4 3
1 2
julia> sort!(A, dims = 1); A
2×2 Matrix{Int64}:
1 2
4 3
julia> sort!(A, dims = 2); A
2×2 Matrix{Int64}:
1 2
3 4sort!(v; alg::Base.Sort.Algorithm=Base.Sort.defalg(v), lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward)ベクター v をその場でソートします。デフォルトでは安定したアルゴリズムが使用されます:等しいと比較される要素の順序は保持されます。特定のアルゴリズムは alg キーワードを介して選択できます(利用可能なアルゴリズムについては Sorting Algorithms を参照してください)。
要素は最初に by 関数で変換され、その後 lt 関数または order に従って比較されます。最後に、rev=true の場合は結果の順序が逆転されます(これにより前方の安定性が保持されます:等しいと比較される要素は逆転されません)。現在の実装では、各比較の前に by 変換が適用され、要素ごとに一度だけではありません。
isless 以外の lt を Base.Order.Forward または Base.Order.Reverse 以外の order と一緒に渡すことは許可されていません。それ以外はすべてのオプションは独立しており、すべての可能な組み合わせで一緒に使用できます。order は "by" 変換を含むこともでき、その場合は by キーワードで定義された後に適用されます。order 値に関する詳細は Alternate Orderings のドキュメントを参照してください。
2つの要素間の関係は次のように定義されます(rev=true の場合は「小さい」と「大きい」が交換されます):
xはyより小さい場合、lt(by(x), by(y))(またはBase.Order.lt(order, by(x), by(y)))が真を返します。xはyより大きい場合、yがxより小さいです。xとyは互いに小さくない場合、等価です(「比較不能」は「等価」の同義語として時々使用されます)。
sort! の結果は、すべての要素が前の要素より大きいか等価であるという意味でソートされています。
lt 関数は厳密な弱順序を定義する必要があります。つまり、次の条件を満たさなければなりません:
- 非反射的:
lt(x, x)は常にfalseを返す。 - 非対称的:
lt(x, y)が真を返す場合、lt(y, x)は偽を返す。 - 推移的:
lt(x, y) && lt(y, z)はlt(x, z)を含意する。 - 等価における推移的:
!lt(x, y) && !lt(y, x)と!lt(y, z) && !lt(z, y)が一緒にある場合、!lt(x, z) && !lt(z, x)を含意する。言い換えれば:xとyが等価であり、yとzが等価である場合、xとzも等価でなければなりません。
例えば、< は Int 値に対する有効な lt 関数ですが、≤ はそうではありません:それは非反射性に違反します。Float64 値の場合、< でさえ無効です。なぜなら、4番目の条件に違反するからです:1.0 と NaN は等価であり、NaN と 2.0 も等価ですが、1.0 と 2.0 は等価ではありません。
他にも sort、sortperm、sortslices、partialsort!、partialsortperm、issorted、searchsorted、insorted、Base.Order.ord を参照してください。
例
julia> v = [3, 1, 2]; sort!(v); v
3-element Vector{Int64}:
1
2
3
julia> v = [3, 1, 2]; sort!(v, rev = true); v
3-element Vector{Int64}:
3
2
1
julia> v = [(1, "c"), (3, "a"), (2, "b")]; sort!(v, by = x -> x[1]); v
3-element Vector{Tuple{Int64, String}}:
(1, "c")
(2, "b")
(3, "a")
julia> v = [(1, "c"), (3, "a"), (2, "b")]; sort!(v, by = x -> x[2]); v
3-element Vector{Tuple{Int64, String}}:
(3, "a")
(2, "b")
(1, "c")
julia> sort(0:3, by=x->x-2, order=Base.Order.By(abs))
4-element Vector{Int64}:
2
1
3
0
julia> sort(0:3, by=x->x-2, order=Base.Order.By(abs)) == sort(0:3, by=x->abs(x-2))
true
julia> sort([2, NaN, 1, NaN, 3]) # correct sort with default lt=isless
5-element Vector{Float64}:
1.0
2.0
3.0
NaN
NaN
julia> sort([2, NaN, 1, NaN, 3], lt=<) # wrong sort due to invalid lt. This behavior is undefined.
5-element Vector{Float64}:
2.0
NaN
1.0
NaN
3.0Base.sort — Functionsort(A; dims::Integer, alg::Base.Sort.Algorithm=Base.Sort.defalg(A), lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward)与えられた次元に沿って多次元配列 A をソートします。可能なキーワード引数の説明については sort! を参照してください。
配列のスライスをソートするには、sortslices を参照してください。
例
julia> A = [4 3; 1 2]
2×2 Matrix{Int64}:
4 3
1 2
julia> sort(A, dims = 1)
2×2 Matrix{Int64}:
1 2
4 3
julia> sort(A, dims = 2)
2×2 Matrix{Int64}:
3 4
1 2sort(v::Union{AbstractVector, NTuple}; alg::Base.Sort.Algorithm=Base.Sort.defalg(v), lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward)sort! のバリアントで、v のソートされたコピーを返し、v 自体は変更されません。
例
julia> v = [3, 1, 2];
julia> sort(v)
3-element Vector{Int64}:
1
2
3
julia> v
3-element Vector{Int64}:
3
1
2Base.sortperm — Functionsortperm(A; alg::Base.Sort.Algorithm=Base.Sort.DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward, [dims::Integer])配列 A を指定された次元でソートされた順序にするための置換ベクトルまたは配列 I を返します。A が複数の次元を持つ場合、dims キーワード引数を指定する必要があります。順序は sort! と同じキーワードを使用して指定されます。置換は、ソートアルゴリズムが不安定であっても安定であることが保証されており、等しい要素のインデックスは昇順で表示されます。
他にも sortperm!、partialsortperm、invperm、indexin を参照してください。配列のスライスをソートするには、sortslices を参照してください。
例
julia> v = [3, 1, 2];
julia> p = sortperm(v)
3-element Vector{Int64}:
2
3
1
julia> v[p]
3-element Vector{Int64}:
1
2
3
julia> A = [8 7; 5 6]
2×2 Matrix{Int64}:
8 7
5 6
julia> sortperm(A, dims = 1)
2×2 Matrix{Int64}:
2 4
1 3
julia> sortperm(A, dims = 2)
2×2 Matrix{Int64}:
3 1
2 4Base.Sort.InsertionSort — Constant挿入ソート挿入ソートアルゴリズムを使用します。
挿入ソートは、コレクションを1つの要素ずつ横断し、各要素を出力ベクターの正しいソートされた位置に挿入します。
特徴:
- 安定: 等しいと比較される要素の順序を保持します
(例:"a"と"A"は大文字と小文字を無視した文字のソートで)。
- メモリ内でのインプレース。
- ソートされる要素の数に対して二次性能:
小さなコレクションには適していますが、大きなコレクションには使用すべきではありません。
Base.Sort.MergeSort — ConstantMergeSortソート関数がマージソートアルゴリズムを使用することを示します。マージソートはコレクションをサブコレクションに分割し、それらを繰り返しマージし、各ステップで各サブコレクションをソートし、最終的に全体のコレクションがソートされた形で再結合されるまで続けます。
特徴:
- 安定: 等しいと比較される要素の順序を保持します(例: 大文字と小文字を無視した文字のソートにおける "a" と "A")。
- メモリ内で インプレース ではありません。
- 分割統治 ソート戦略。
- 大規模コレクションに対して 良好なパフォーマンス を発揮しますが、通常は
QuickSortほど速くはありません。
Base.Sort.QuickSort — Constantクイックソートソート関数がクイックソートアルゴリズムを使用する必要があることを示します。これは安定ではありません。
特徴:
- 安定ではない: 等しいと比較される要素の順序を保持しません(例:"a"と"A"が大文字と小文字を無視した文字のソートで)。
- インプレースでメモリ内。
- 分割統治法:
マージソートに似たソート戦略。 - 大規模コレクションに対して良好なパフォーマンス。
Base.Sort.PartialQuickSort — TypePartialQuickSort{T <: Union{Integer,OrdinalRange}}ソート関数が部分クイックソートアルゴリズムを使用する必要があることを示します。PartialQuickSort(k)はQuickSortのようなもので、vが完全にソートされていた場合にv[k]に配置される要素を見つけてソートすることだけが求められます。
特徴:
- 安定ではない: 同じ値を比較した場合の要素の順序を保持しません(例: 大文字と小文字を無視した文字のソートにおける "a" と "A")。
- メモリ内での。
- 分割統治法:
MergeSortに似たソート戦略。
PartialQuickSort(k)は必ずしも配列全体をソートするわけではないことに注意してください。例えば、
julia> x = rand(100);
julia> k = 50:100;
julia> s1 = sort(x; alg=QuickSort);
julia> s2 = sort(x; alg=PartialQuickSort(k));
julia> map(issorted, (s1, s2))
(true, false)
julia> map(x->issorted(x[k]), (s1, s2))
(true, true)
julia> s1[k] == s2[k]
trueBase.Sort.sortperm! — Functionsortperm!(ix, A; alg::Base.Sort.Algorithm=Base.Sort.DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward, [dims::Integer])sortperm と同様ですが、A と同じ axes を持つ事前に割り当てられたインデックスベクトルまたは配列 ix を受け入れます。ix は LinearIndices(A) の値を含むように初期化されます。
例
julia> v = [3, 1, 2]; p = zeros(Int, 3);
julia> sortperm!(p, v); p
3-element Vector{Int64}:
2
3
1
julia> v[p]
3-element Vector{Int64}:
1
2
3
julia> A = [8 7; 5 6]; p = zeros(Int,2, 2);
julia> sortperm!(p, A; dims=1); p
2×2 Matrix{Int64}:
2 4
1 3
julia> sortperm!(p, A; dims=2); p
2×2 Matrix{Int64}:
3 1
2 4Base.sortslices — Functionsortslices(A; dims, alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)配列 A のスライスをソートします。必須のキーワード引数 dims は整数または整数のタプルでなければなりません。これは、スライスがソートされる次元を指定します。
例えば、A が行列の場合、dims=1 は行をソートし、dims=2 は列をソートします。1次元スライスに対するデフォルトの比較関数は、辞書式にソートされることに注意してください。
残りのキーワード引数については、sort! のドキュメントを参照してください。
例
julia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1) # 行をソート
3×3 Matrix{Int64}:
-1 6 4
7 3 5
9 -2 8
julia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1, lt=(x,y)->isless(x[2],y[2]))
3×3 Matrix{Int64}:
9 -2 8
7 3 5
-1 6 4
julia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1, rev=true)
3×3 Matrix{Int64}:
9 -2 8
7 3 5
-1 6 4
julia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2) # 列をソート
3×3 Matrix{Int64}:
3 5 7
-1 -4 6
-2 8 9
julia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2, alg=InsertionSort, lt=(x,y)->isless(x[2],y[2]))
3×3 Matrix{Int64}:
5 3 7
-4 -1 6
8 -2 9
julia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2, rev=true)
3×3 Matrix{Int64}:
7 5 3
6 -4 -1
9 8 -2高次元
sortslices は高次元にも自然に拡張されます。例えば、A が 2x2x2 の配列である場合、sortslices(A, dims=3) は3次元内のスライスをソートし、2x2 のスライス A[:, :, 1] と A[:, :, 2] を比較関数に渡します。高次元スライスにはデフォルトの順序はありませんが、by または lt のキーワード引数を使用してそのような順序を指定できます。
dims がタプルの場合、dims 内の次元の順序は重要であり、スライスの線形順序を指定します。例えば、A が三次元で dims が (1, 2) の場合、最初の2つの次元の順序が再配置され、残りの3次元のスライスがソートされます。代わりに dims が (2, 1) の場合、同じスライスが取られますが、結果の順序は行優先になります。
高次元の例
julia> A = [4 3; 2 1 ;;; 'A' 'B'; 'C' 'D']
2×2×2 Array{Any, 3}:
[:, :, 1] =
4 3
2 1
[:, :, 2] =
'A' 'B'
'C' 'D'
julia> sortslices(A, dims=(1,2))
2×2×2 Array{Any, 3}:
[:, :, 1] =
1 3
2 4
[:, :, 2] =
'D' 'B'
'C' 'A'
julia> sortslices(A, dims=(2,1))
2×2×2 Array{Any, 3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
'D' 'C'
'B' 'A'
julia> sortslices(reshape([5; 4; 3; 2; 1], (1,1,5)), dims=3, by=x->x[1,1])
1×1×5 Array{Int64, 3}:
[:, :, 1] =
1
[:, :, 2] =
2
[:, :, 3] =
3
[:, :, 4] =
4
[:, :, 5] =
5Order-Related Functions
Base.issorted — Functionissorted(v, lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward)コレクションがソートされた順序にあるかどうかをテストします。キーワードは、sort! ドキュメントに記載されているように、どの順序がソートされたと見なされるかを変更します。
例
julia> issorted([1, 2, 3])
true
julia> issorted([(1, "b"), (2, "a")], by = x -> x[1])
true
julia> issorted([(1, "b"), (2, "a")], by = x -> x[2])
false
julia> issorted([(1, "b"), (2, "a")], by = x -> x[2], rev=true)
true
julia> issorted([1, 2, -2, 3], by=abs)
trueBase.Sort.searchsorted — Functionsearchsorted(v, x; by=identity, lt=isless, rev=false)v内でxと等価な値のインデックスの範囲を返します。vにxと等価な値が含まれていない場合は、挿入ポイントに位置する空の範囲を返します。ベクトルvは、キーワードで定義された順序に従ってソートされている必要があります。キーワードの意味と等価性の定義については、sort!を参照してください。by関数は、検索される値xとv内の値の両方に適用されることに注意してください。
範囲は一般的に二分探索を使用して見つけられますが、一部の入力に対しては最適化された実装があります。
関連項目: searchsortedfirst, sort!, insorted, findall.
例
julia> searchsorted([1, 2, 4, 5, 5, 7], 4) # 単一の一致
3:3
julia> searchsorted([1, 2, 4, 5, 5, 7], 5) # 複数の一致
4:5
julia> searchsorted([1, 2, 4, 5, 5, 7], 3) # 一致なし、中間に挿入
3:2
julia> searchsorted([1, 2, 4, 5, 5, 7], 9) # 一致なし、末尾に挿入
7:6
julia> searchsorted([1, 2, 4, 5, 5, 7], 0) # 一致なし、先頭に挿入
1:0
julia> searchsorted([1=>"one", 2=>"two", 2=>"two", 4=>"four"], 2=>"two", by=first) # ペアのキーを比較
2:3Base.Sort.searchsortedfirst — Functionsearchsortedfirst(v, x; by=identity, lt=isless, rev=false)vの中でxよりも前に順序付けられていない最初の値のインデックスを返します。もしvのすべての値がxの前に順序付けられている場合は、lastindex(v) + 1を返します。
ベクトルvは、キーワードによって定義された順序に従ってソートされている必要があります。返されたインデックスにxをinsert!すると、ソートされた順序が維持されます。キーワードの意味と使用法についてはsort!を参照してください。by関数は、検索される値xとvの値の両方に適用されることに注意してください。
インデックスは一般的に二分探索を使用して見つけられますが、一部の入力に対しては最適化された実装があります。
他にも: searchsortedlast, searchsorted, findfirst.
例
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 4) # 単一の一致
3
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 5) # 複数の一致
4
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 3) # 一致なし、中央に挿入
3
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 9) # 一致なし、末尾に挿入
7
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 0) # 一致なし、先頭に挿入
1
julia> searchsortedfirst([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # ペアのキーを比較
3Base.Sort.searchsortedlast — Functionsearchsortedlast(v, x; by=identity, lt=isless, rev=false)vの中でxの後に順序付けされていない最後の値のインデックスを返します。もしvのすべての値がxの後に順序付けされている場合、firstindex(v) - 1を返します。
ベクトルvは、キーワードによって定義された順序に従ってソートされている必要があります。返されたインデックスのすぐ後にxをinsert!すると、ソートされた順序が維持されます。キーワードの意味と使用法についてはsort!を参照してください。by関数は、検索される値xとvの値の両方に適用されることに注意してください。
インデックスは一般的に二分探索を使用して見つけられますが、一部の入力に対しては最適化された実装があります。
例
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 4) # 単一の一致
3
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 5) # 複数の一致
5
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 3) # 一致なし、中間に挿入
2
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 9) # 一致なし、末尾に挿入
6
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 0) # 一致なし、先頭に挿入
0
julia> searchsortedlast([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # ペアのキーを比較
2Base.Sort.insorted — Functioninsorted(x, v; by=identity, lt=isless, rev=false) -> Boolベクトル v に x と同等の値が含まれているかどうかを判断します。ベクトル v はキーワードで定義された順序に従ってソートされている必要があります。キーワードの意味や同等性の定義については sort! を参照してください。by 関数は、検索される値 x と v の値の両方に適用されることに注意してください。
チェックは一般的に二分探索を使用して行われますが、一部の入力に対しては最適化された実装があります。
他にも in を参照してください。
例
julia> insorted(4, [1, 2, 4, 5, 5, 7]) # 単一の一致
true
julia> insorted(5, [1, 2, 4, 5, 5, 7]) # 複数の一致
true
julia> insorted(3, [1, 2, 4, 5, 5, 7]) # 一致なし
false
julia> insorted(9, [1, 2, 4, 5, 5, 7]) # 一致なし
false
julia> insorted(0, [1, 2, 4, 5, 5, 7]) # 一致なし
false
julia> insorted(2=>"TWO", [1=>"one", 2=>"two", 4=>"four"], by=first) # ペアのキーを比較
trueBase.Sort.partialsort! — Functionpartialsort!(v, k; by=identity, lt=isless, rev=false)ベクトル v をインプレースで部分的にソートし、インデックス k の値(または k が範囲の場合は隣接する値の範囲)が配列が完全にソートされた場合に出現する位置に配置されるようにします。k が単一のインデックスの場合、その値が返されます。k が範囲の場合、そのインデックスにある値の配列が返されます。partialsort! は入力配列を完全にソートしない場合があることに注意してください。
キーワード引数については、sort! のドキュメントを参照してください。
例
julia> a = [1, 2, 4, 3, 4]
5-element Vector{Int64}:
1
2
4
3
4
julia> partialsort!(a, 4)
4
julia> a
5-element Vector{Int64}:
1
2
3
4
4
julia> a = [1, 2, 4, 3, 4]
5-element Vector{Int64}:
1
2
4
3
4
julia> partialsort!(a, 4, rev=true)
2
julia> a
5-element Vector{Int64}:
4
4
3
2
1Base.Sort.partialsort — Functionpartialsort(v, k, by=identity, lt=isless, rev=false)partialsort! のバリアントで、部分的にソートする前に v をコピーし、partialsort! と同じものを返しますが、v は変更されません。
Base.Sort.partialsortperm — Functionpartialsortperm(v, k; by=identity, lt=isless, rev=false)ベクトル v の部分的な順列 I を返します。これにより、v[I] はインデックス k での v の完全にソートされたバージョンの値を返します。k が範囲の場合、インデックスのベクトルが返されます。k が整数の場合、単一のインデックスが返されます。順序は sort! と同じキーワードを使用して指定されます。順列は安定しており、同じ要素のインデックスは昇順で表示されます。
この関数は、sortperm(...)[k] を呼び出すよりも効率的ですが、同等です。
例
julia> v = [3, 1, 2, 1];
julia> v[partialsortperm(v, 1)]
1
julia> p = partialsortperm(v, 1:3)
3-element view(::Vector{Int64}, 1:3) with eltype Int64:
2
4
3
julia> v[p]
3-element Vector{Int64}:
1
1
2Base.Sort.partialsortperm! — Functionpartialsortperm!(ix, v, k; by=identity, lt=isless, rev=false)partialsortpermと同様ですが、vと同じサイズの事前に割り当てられたインデックスベクトルixを受け入れ、vのインデックスの(順列の)格納に使用されます。
ixはvのインデックスを含むように初期化されます。
(通常、vのインデックスは1:length(v)ですが、vがOffsetArrayのような非1ベースのインデックスを持つ代替配列型である場合、ixはそれらの同じインデックスを共有しなければなりません)
戻り値として、ixはkのインデックスがソートされた位置にあることが保証されており、次のようになります。
partialsortperm!(ix, v, k);
v[ix[k]] == partialsort(v, k)戻り値は、kが整数の場合はixのk番目の要素、kが範囲の場合はixへのビューです。
例
julia> v = [3, 1, 2, 1];
julia> ix = Vector{Int}(undef, 4);
julia> partialsortperm!(ix, v, 1)
2
julia> ix = [1:4;];
julia> partialsortperm!(ix, v, 2:3)
2-element view(::Vector{Int64}, 2:3) with eltype Int64:
4
3Sorting Algorithms
現在、ベースのJuliaで公開されているソートアルゴリズムは4つあります:
デフォルトでは、sort 関数のファミリーは、ほとんどの入力に対して高速な安定ソートアルゴリズムを使用します。正確なアルゴリズムの選択は、将来のパフォーマンス向上を可能にするための実装の詳細です。現在、入力の種類、サイズ、および構成に基づいて、RadixSort、ScratchQuickSort、InsertionSort、および CountingSort のハイブリッドが使用されています。実装の詳細は変更される可能性がありますが、現在は ??Base.DEFAULT_STABLE の拡張ヘルプおよびそこにリストされている内部ソートアルゴリズムのドックストリングで利用可能です。
alg キーワードを使用して、好みのアルゴリズムを明示的に指定できます(例: sort!(v, alg=PartialQuickSort(10:20)))。また、Base.Sort.defalg 関数に特化したメソッドを追加することで、カスタムタイプのデフォルトのソートアルゴリズムを再構成することもできます。例えば、InlineStrings.jl は次のメソッドを定義します:
Base.Sort.defalg(::AbstractArray{<:Union{SmallInlineStrings, Missing}}) = InlineStringSortデフォルトのソートアルゴリズム(Base.Sort.defalgによって返される)は、Julia 1.9以降、安定であることが保証されています。以前のバージョンでは、数値配列をソートする際に不安定なエッジケースがありました。
Alternate Orderings
デフォルトでは、sort、searchsorted、および関連する関数は、どの要素が先に来るべきかを判断するために isless を使用して2つの要素を比較します。Base.Order.Ordering 抽象型は、同じ要素のセットに対して代替の順序を定義するためのメカニズムを提供します。sort! のようなソート関数を呼び出すときに、order というキーワード引数で Ordering のインスタンスを提供することができます。
Orderingのインスタンスは、Base.Order.lt関数を通じて順序を定義します。この関数は、islessの一般化として機能します。カスタムOrderingに対するこの関数の動作は、strict weak orderのすべての条件を満たさなければなりません。詳細と有効および無効なlt関数の例については、sort!を参照してください。
Base.Order.Ordering — TypeBase.Order.Ordering要素の集合に対する厳密な弱順序を表す抽象型です。詳細についてはsort!を参照してください。
順序に従って2つの要素を比較するには、Base.Order.ltを使用してください。
Base.Order.lt — Functionlt(o::Ordering, a, b) -> Boolaがbよりもoに従って小さいかどうかをテストします。
Base.Order.ord — Functionord(lt, by, rev::Union{Bool, Nothing}, order::Ordering=Forward)Ordering オブジェクトを sort! で使用されるのと同じ引数から構築します。要素は最初に関数 by(これは [identity](@ref)である可能性があります)によって変換され、その後、関数 lt または既存の順序 order に従って比較されます。lt は isless であるか、sort! の lt パラメータと同じルールに従う関数である必要があります。最後に、rev=true の場合、結果の順序は逆になります。
isless 以外の lt を Base.Order.Forward または Base.Order.Reverse 以外の order と一緒に渡すことは許可されていません。それ以外の場合、すべてのオプションは独立しており、すべての可能な組み合わせで一緒に使用できます。
Base.Order.Forward — ConstantBase.Order.Forwardisless によるデフォルトの順序付け。
Base.Order.ReverseOrdering — TypeReverseOrdering(fwd::Ordering=Forward)順序を逆にするラッパーです。
与えられた Ordering o に対して、すべての a, b に対して以下が成り立ちます:
lt(ReverseOrdering(o), a, b) == lt(o, b, a)Base.Order.Reverse — ConstantBase.Order.Reverseisless に従った逆順序。
Base.Order.By — TypeBy(by, order::Ordering=Forward)Orderingは、要素が関数byによって変換された後にorderを適用します。
Base.Order.Lt — TypeLt(lt)Ordering は lt(a, b) を呼び出して要素を比較します。lt は sort! の lt パラメータと同じルールに従わなければなりません。
Base.Order.Perm — TypePerm(order::Ordering, data::AbstractVector)Orderingはdataのインデックスに対して、data[i]がdata[j]よりも小さい場合にiがjよりも小さいとします。data[i]とdata[j]が等しい場合は、iとjは数値で比較されます。