Skip to content

Commit be3221f

Browse files
LilithHafnernsajko
andauthored
Support sort(keys(::Dict)) and sort(values(::Dict)) (#56978)
Part of the sorting iterables saga: #38328 #46104 #51977 #52010 #54494 --------- Co-authored-by: Neven Sajko <[email protected]>
1 parent abb1313 commit be3221f

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

NEWS.md

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ New library functions
2525
New library features
2626
--------------------
2727

28+
`sort(keys(::Dict))` and `sort(values(::Dict))` now automatically collect, they previously threw ([#56978]).
29+
2830
Standard library changes
2931
------------------------
3032

base/sort.jl

+17-2
Original file line numberDiff line numberDiff line change
@@ -1620,7 +1620,7 @@ defalg(v::AbstractArray) = DEFAULT_STABLE
16201620
defalg(v::AbstractArray{<:Union{Number, Missing}}) = DEFAULT_UNSTABLE
16211621
defalg(v::AbstractArray{Missing}) = DEFAULT_UNSTABLE # for method disambiguation
16221622
defalg(v::AbstractArray{Union{}}) = DEFAULT_UNSTABLE # for method disambiguation
1623-
defalg(v::NTuple) = DEFAULT_STABLE
1623+
defalg(v) = DEFAULT_STABLE
16241624

16251625
"""
16261626
sort!(v; alg::Base.Sort.Algorithm=Base.Sort.defalg(v), lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward)
@@ -1739,13 +1739,20 @@ function sort!(v::AbstractVector{T};
17391739
end
17401740

17411741
"""
1742-
sort(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)
1742+
sort(v; alg::Base.Sort.Algorithm=Base.Sort.defalg(v), lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward)
1743+
sort(v::NTuple; kws...)::NTuple
17431744
17441745
Variant of [`sort!`](@ref) that returns a sorted copy of `v` leaving `v` itself unmodified.
17451746
1747+
When calling `sort` on the [`keys`](@ref) or [`values](@ref) of a dictionary, `v` is
1748+
collected and then sorted in place.
1749+
17461750
!!! compat "Julia 1.12"
17471751
Sorting `NTuple`s requires Julia 1.12 or later.
17481752
1753+
!!! compat "Julia 1.13"
1754+
Sorting keys sets and values iterators requires Julia 1.13 or later.
1755+
17491756
# Examples
17501757
```jldoctest
17511758
julia> v = [3, 1, 2];
@@ -1761,10 +1768,18 @@ julia> v
17611768
3
17621769
1
17631770
2
1771+
1772+
julia> sort(values(Dict('a'=>2, 'b'=>1)))
1773+
2-element Vector{Int64}:
1774+
1
1775+
2
17641776
```
17651777
"""
17661778
sort(v::AbstractVector; kws...) = sort!(copymutable(v); kws...)
17671779

1780+
const COLLECT_ON_SORT_TYPES = Union{Base.KeySet, Base.ValueIterator}
1781+
sort(v::COLLECT_ON_SORT_TYPES; kws...) = sort!(collect(v); kws...)
1782+
17681783
function sort(x::NTuple;
17691784
alg::Algorithm=defalg(x),
17701785
lt=isless,

test/sorting.jl

+8
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,14 @@ end
110110
@test Base.infer_return_type(sort, Tuple{Tuple{Vararg{Int}}}) == Tuple{Vararg{Int}}
111111
end
112112

113+
@testset "KeySet and ValueIterator" begin
114+
x = Dict(rand() => randstring() for _ in 1:10)
115+
x0 = deepcopy(x)
116+
@test issorted(sort(keys(x))::Vector{Float64})
117+
@test issorted(sort(values(x))::Vector{String})
118+
@test x == x0
119+
end
120+
113121
@testset "partialsort" begin
114122
@test partialsort([3,6,30,1,9],3) == 6
115123
@test partialsort([3,6,30,1,9],3:4) == [6,9]

0 commit comments

Comments
 (0)