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
 1

sort は、入力を変更せずにソートされたコピーを構築します。既存の配列を変更するために、ソート関数の「バン」バージョンを使用します:

julia> a = [2,3,1];

julia> sort!(a);

julia> a
3-element Vector{Int64}:
 1
 2
 3

配列を直接ソートする代わりに、配列をソートされた順序に配置するインデックスの順列を計算することができます:

julia> v = randn(5)
5-element Array{Float64,1}:
  0.297288
  0.382396
 -0.597634
 -0.0104452
 -0.839027

julia> p = sortperm(v)
5-element Array{Int64,1}:
 5
 3
 4
 1
 2

julia> v[p]
5-element Array{Float64,1}:
 -0.839027
 -0.597634
 -0.0104452
  0.297288
  0.382396

配列は、その値の任意の変換に従ってソートすることができます:

julia> sort(v, by=abs)
5-element Array{Float64,1}:
 -0.0104452
  0.297288
  0.382396
 -0.597634
 -0.839027

または変換によって逆の順序で:

julia> sort(v, by=abs, rev=true)
5-element Array{Float64,1}:
 -0.839027
 -0.597634
  0.382396
  0.297288
 -0.0104452

必要に応じて、ソートアルゴリズムを選択できます:

julia> sort(v, alg=InsertionSort)
5-element Array{Float64,1}:
 -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!Function
sort!(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

ベクター v をその場でソートします。デフォルトでは安定したアルゴリズムが使用されます:等しいと比較される要素の順序は保持されます。特定のアルゴリズムは alg キーワードを介して選択できます(利用可能なアルゴリズムについては Sorting Algorithms を参照してください)。

要素は最初に by 関数で変換され、その後 lt 関数または order に従って比較されます。最後に、rev=true の場合は結果の順序が逆転されます(これにより前方の安定性が保持されます:等しいと比較される要素は逆転されません)。現在の実装では、各比較の前に by 変換が適用され、要素ごとに一度だけではありません。

isless 以外の ltBase.Order.Forward(@ref) または Base.Order.Reverse(@ref) 以外の order と一緒に渡すことは許可されていません。それ以外はすべてのオプションは独立しており、すべての可能な組み合わせで一緒に使用できます。order は "by" 変換を含むこともでき、その場合は by キーワードで定義された後に適用されます。order 値に関する詳細は Alternate Orderings のドキュメントを参照してください。

2つの要素間の関係は次のように定義されます(rev=true の場合は「小さい」と「大きい」が交換されます):

  • xy より小さい場合、lt(by(x), by(y))(または Base.Order.lt(order, by(x), by(y)))が真を返します。
  • xy より大きい場合、yx より小さいです。
  • xy は互いに小さくない場合、等価です(「比較不能」は「等価」の同義語として時々使用されます)。

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) を含意する。言い換えれば:xy が等価であり、yz が等価である場合、xz も等価でなければなりません。

例えば、<Int 値に対する有効な lt 関数ですが、 は無効です:反射性を侵害します。Float64 値の場合、< でさえ無効です。なぜなら、4番目の条件を侵害するからです:1.0NaN は等価であり、NaN2.0 も等価ですが、1.02.0 は等価ではありません。

他にも sortsortpermsortslicespartialsort!partialsortpermissortedsearchsortedinsortedBase.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)) # same as sort(0:3, by=abs(x->x-2))
4-element Vector{Int64}:
 2
 1
 3
 0

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.0
source
sort!(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

多次元配列 A を次元 dims に沿ってソートします。可能なキーワード引数の説明については、sort! の一次元バージョンを参照してください。

配列のスライスをソートするには、sortslices を参照してください。

Julia 1.1

この関数は少なくとも Julia 1.1 を必要とします。

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  4
source
Base.sortFunction
sort(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=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
 2
source
sort(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=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  2
source
Base.sortpermFunction
sortperm(A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])

配列 A を与えられた次元でソートされた順序にするための置換ベクトルまたは配列 I を返します。A が複数の次元を持つ場合、dims キーワード引数を指定する必要があります。順序は sort! と同じキーワードを使用して指定されます。置換は、ソートアルゴリズムが不安定であっても安定であることが保証されており、等しい要素のインデックスは昇順で表示されます。

他に sortperm!partialsortperminvpermindexin も参照してください。配列のスライスをソートするには、sortslices を参照してください。

Julia 1.9

dims を受け入れるメソッドは、少なくとも Julia 1.9 が必要です。

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  4
source
Base.Sort.InsertionSortConstant
挿入ソート

挿入ソートアルゴリズムを使用します。

挿入ソートは、コレクションを1つの要素ずつ走査し、各要素を出力ベクターの正しいソートされた位置に挿入します。

特徴:

  • 安定性: 等しいと比較される要素の順序を保持します

(例: 大文字と小文字を無視した文字のソートにおける "a" と "A")。

  • メモリ内でのインプレース
  • 二次性能:ソートされる要素の数に対して:

小さなコレクションには適していますが、大きなコレクションには使用すべきではありません。

source
Base.Sort.MergeSortConstant
マージソート

ソート関数がマージソートアルゴリズムを使用することを示します。マージソートはコレクションをサブコレクションに分割し、それらを繰り返しマージし、各ステップで各サブコレクションをソートし、最終的に全体のコレクションがソートされた形で再結合されるまで続けます。

特徴:

  • 安定: 等しいと比較される要素の順序を保持します(例: 大文字と小文字を無視した文字のソートにおける "a" と "A")。
  • メモリ内でのインプレースではない
  • 分割統治ソート戦略。
  • 大規模コレクションに対して良好なパフォーマンスを発揮しますが、通常はクイックソートほど速くはありません。
source
Base.Sort.QuickSortConstant
クイックソート

ソート関数はクイックソートアルゴリズムを使用する必要があり、これは安定ではありません

特徴:

  • 安定ではない: 等しいと比較される要素の順序を保持しません(例:"a"と"A"が大文字と小文字を無視した文字のソートで)。
  • インプレースでメモリ内。
  • 分割統治法: マージソートに似たソート戦略。
  • 大規模コレクションに対して良好なパフォーマンス
source
Base.Sort.PartialQuickSortType
PartialQuickSort{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]
true
source
Base.Sort.sortperm!Function
sortperm!(ix, A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])

sortpermと同様ですが、Aと同じaxesを持つ事前に割り当てられたインデックスベクトルまたは配列ixを受け入れます。ixLinearIndices(A)の値を含むように初期化されます。

Warning

変更された引数が他の引数とメモリを共有している場合、動作が予期しないものになることがあります。

Julia 1.9

dimsを受け入れるメソッドは、少なくともJulia 1.9が必要です。

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  4
source
Base.sortslicesFunction
sortslices(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] =
 5
source
Base.issortedFunction
issorted(v, lt=isless, by=identity, rev::Bool=false, order::Ordering=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)
true
source
Base.Sort.searchsortedFunction
searchsorted(v, x; by=identity, lt=isless, rev=false)

v内の値がxと等しいインデックスの範囲を返します。vxと等しい値が含まれていない場合は、挿入位置にある空の範囲を返します。ベクトルvは、キーワードで定義された順序に従ってソートされている必要があります。キーワードの意味と同値の定義については、sort!を参照してください。by関数は、検索される値xv内の値の両方に適用されます。

範囲は一般的に二分探索を使用して見つけられますが、一部の入力に対しては最適化された実装があります。

関連情報: 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:3
source
Base.Sort.searchsortedfirstFunction
searchsortedfirst(v, x; by=identity, lt=isless, rev=false)

xよりも前に順序付けられていないvの最初の値のインデックスを返します。もしvのすべての値がxの前に順序付けられている場合、lastindex(v) + 1を返します。

ベクトルvは、キーワードで定義された順序に従ってソートされている必要があります。返されたインデックスでxinsert!すると、ソートされた順序が維持されます。キーワードの意味と使用法については、sort!を参照してください。by関数は、検索される値xvの値の両方に適用されることに注意してください。

インデックスは一般的に二分探索を使用して見つけられますが、一部の入力に対しては最適化された実装があります。

関連情報: 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) # ペアのキーを比較
3
source
Base.Sort.searchsortedlastFunction
searchsortedlast(v, x; by=identity, lt=isless, rev=false)

vの中でxの後に順序付けされていない最後の値のインデックスを返します。もしvのすべての値がxの後に順序付けされている場合、firstindex(v) - 1を返します。

ベクトルvは、キーワードによって定義された順序に従ってソートされている必要があります。返されたインデックスのすぐ後にxinsert!すると、ソートされた順序が維持されます。キーワードの意味と使用法についてはsort!を参照してください。by関数は、検索される値xvの値の両方に適用されることに注意してください。

インデックスは一般的に二分探索を使用して見つけられますが、一部の入力に対しては最適化された実装があります。

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) # ペアのキーを比較
2
source
Base.Sort.insortedFunction
insorted(x, v; by=identity, lt=isless, rev=false) -> Bool

ベクトル vx と等価な値が含まれているかどうかを判断します。ベクトル v はキーワードで定義された順序に従ってソートされている必要があります。キーワードの意味や等価性の定義については sort! を参照してください。by 関数は、検索される値 xv の値の両方に適用されます。

チェックは一般的に二分探索を使用して行われますが、一部の入力に対しては最適化された実装があります。

さらに 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) # ペアのキーを比較
true
Julia 1.6

insorted は Julia 1.6 で追加されました。

source
Base.Sort.partialsort!Function
partialsort!(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
 1
source
Base.Sort.partialsortFunction
partialsort(v, k, by=identity, lt=isless, rev=false)

partialsort! のバリアントで、部分的にソートする前に v をコピーし、partialsort! と同じものを返しますが、v は変更されません。

source
Base.Sort.partialsortpermFunction
partialsortperm(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
 2
source
Base.Sort.partialsortperm!Function
partialsortperm!(ix, v, k; by=identity, lt=isless, rev=false)

partialsortpermと同様ですが、vと同じサイズの事前に割り当てられたインデックスベクトルixを受け入れ、vのインデックスの(順列の)格納に使用されます。

ixvのインデックスを含むように初期化されます。

(通常、vのインデックスは1:length(v)ですが、vOffsetArrayのような非1ベースのインデックスを持つ代替配列型である場合、ixはそれらの同じインデックスを共有しなければなりません)

戻り値として、ixkのインデックスがソートされた位置にあることが保証されており、次のようになります。

partialsortperm!(ix, v, k);
v[ix[k]] == partialsort(v, k)

戻り値は、kが整数の場合はixk番目の要素、kが範囲の場合はixへのビューです。

Warning

変更された引数が他の引数とメモリを共有している場合、動作が予期しないものになることがあります。

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
 3

```

source

Sorting Algorithms

現在、ベースのJuliaには公開されている4つのソートアルゴリズムがあります:

デフォルトでは、sortファミリーの関数は、ほとんどの入力に対して高速な安定ソートアルゴリズムを使用します。正確なアルゴリズムの選択は、将来のパフォーマンス向上を可能にするための実装の詳細です。現在、入力の種類、サイズ、および構成に基づいて、RadixSortScratchQuickSortInsertionSort、およびCountingSortのハイブリッドが使用されています。実装の詳細は変更される可能性がありますが、現在は??Base.DEFAULT_STABLEの拡張ヘルプおよびそこにリストされている内部ソートアルゴリズムのドックストリングで利用可能です。

alg キーワードを使用して、好みのアルゴリズムを明示的に指定できます(例: sort!(v, alg=PartialQuickSort(10:20)))。また、カスタムタイプのデフォルトのソートアルゴリズムを再構成するには、Base.Sort.defalg 関数に特化したメソッドを追加します。例えば、InlineStrings.jl は次のメソッドを定義します:

Base.Sort.defalg(::AbstractArray{<:Union{SmallInlineStrings, Missing}}) = InlineStringSort
Julia 1.9

デフォルトのソートアルゴリズム(Base.Sort.defalgによって返される)は、Julia 1.9以降、安定であることが保証されています。以前のバージョンでは、数値配列をソートする際に不安定なエッジケースがありました。

Alternate Orderings

デフォルトでは、sortsearchsorted、および関連する関数は、islessを使用して2つの要素を比較し、どちらが先に来るべきかを判断します。Base.Order.Ordering抽象型は、同じ要素のセットに対して代替の順序を定義するためのメカニズムを提供します。sort!のようなソート関数を呼び出す際に、Orderingのインスタンスをキーワード引数orderと共に提供することができます。

Orderingのインスタンスは、Base.Order.lt関数を通じて順序を定義します。この関数は、islessの一般化として機能します。カスタムOrderingに対するこの関数の動作は、strict weak orderのすべての条件を満たさなければなりません。詳細と有効および無効なlt関数の例については、sort!を参照してください。

Base.Order.OrderingType
Base.Order.Ordering

抽象型で、いくつかの要素の集合に対する厳密な弱順序を表します。詳細についてはsort!を参照してください。

Base.Order.ltを使用して、順序に従って2つの要素を比較します。

source
Base.Order.ltFunction
lt(o::Ordering, a, b) -> Bool

abよりもoに従って小さいかどうかをテストします。

source
Base.Order.ordFunction
ord(lt, by, rev::Union{Bool, Nothing}, order::Ordering=Forward)

同じ引数を使用してsort!オブジェクトからOrderingオブジェクトを構築します。要素は最初に関数by(これはidentityである可能性があります)によって変換され、その後、関数ltまたは既存の順序orderに従って比較されます。ltislessであるか、sort!ltパラメータと同じルールに従う関数である必要があります。最後に、rev=trueの場合、結果の順序は逆になります。

isless以外のltBase.Order.ForwardまたはBase.Order.Reverse以外のorderと一緒に渡すことは許可されていません。それ以外は、すべてのオプションは独立しており、すべての可能な組み合わせで一緒に使用できます。

source
Base.Order.ReverseOrderingType
ReverseOrdering(fwd::Ordering=Forward)

順序を逆にするラッパーです。

与えられた Ordering o に対して、すべての ab に対して以下が成り立ちます:

lt(ReverseOrdering(o), a, b) == lt(o, b, a)
source
Base.Order.ByType
By(by, order::Ordering=Forward)

Orderingは、要素が関数byによって変換された後にorderを適用します。

source
Base.Order.LtType
Lt(lt)

Orderinglt(a, b) を呼び出して要素を比較します。ltsort!lt パラメータと同じルールに従わなければなりません。

source
Base.Order.PermType
Perm(order::Ordering, data::AbstractVector)

Orderingdataのインデックスに対して、data[i]data[j]より小さい場合にijより小さいとします。data[i]data[j]が等しい場合は、ijは数値で比較されます。

source