# sort(keys(Dict(:a =\> 1, :b =\> 2))) throws MethodError

**URL:** https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701
**Category:** General Usage
**Tags:** question
**Created:** [April 20, 2023, 12:31pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701 "2023-04-20T12:31:59Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)
#### Post date: [April 20, 2023, 12:31pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/1 "2023-04-20T12:31:59Z")

</div>

I guess this is rather a discussion:

```julia
sort(keys(Dict(:a => 1, :b => 2)))

```

throws the following MethodError

```julia
ERROR: MethodError: no method matching sort(::Base.KeySet{Symbol, Dict{Symbol, Int64}})
Closest candidates are:
  sort(::AbstractUnitRange) at range.jl:1379
  sort(::AbstractRange) at range.jl:1382
  sort(::SparseArrays.SparseVector{Tv, Ti}; kws...) where {Tv, Ti} at /nix/store/0fxg4zpsp5rbjfxn3hic1534rhagymmr-julia-1.8.5/share/julia/stdlib/v1.8/SparseArrays/src/sparsevector.jl:1994
  ...
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

```

For me this looks like a bug, but it is also quite surprising to find such a bug in julia 1.8  
Hence maybe it is intended? Why should this be intended?

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [April 20, 2023, 12:41pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/2 "2023-04-20T12:41:16Z")

</div>

I guess the clue is in the name `Key*Set*`, sets don’t have an order. You can `collect` the keys into a plain vector for sorting.

---

<div class="post-metadata">

### Author: ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)
#### Post date: [April 20, 2023, 12:47pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/3 "2023-04-20T12:47:31Z")

</div>

thank you, apparently also `sort(Set([1,2,3]))` fails

Still, semantically this is exactly why I call sort, isn’t it? I input something unordered and would like to have it ordered.

And you at least can iterate over a Set, hence why not calling sort on top of it? (neither is sort in place)

From performance perspective it is also not good to collect everything into an intermediate array which you just drop again.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [April 20, 2023, 12:48pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/4 "2023-04-20T12:48:47Z")

</div>

> [@schlichtanders](#):
>
> From performance perspective it is also not good to collect everything into an intermediate array which you just drop again.

You can do `sort!`.

---

<div class="post-metadata">

### Author: ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)
#### Post date: [April 20, 2023, 12:51pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/5 "2023-04-20T12:51:26Z")

</div>

okay, so the workaround is `sort!(collect(Set([1,2,3])))`

probably this is still slower than directly constructing the vector in a sorted manner  
and it looks very error-prone, like you really don’t want to see this in end-user code, something which should be put into another function like `sortset(set) = sort!(collect(set))`.

Hence again I would guess that there should be something for this in `Base`

---

<div class="post-metadata">

### Author: ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)
#### Post date: [April 20, 2023, 12:54pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/6 "2023-04-20T12:54:04Z")

</div>

What is wrong with:

```julia
Base.sort(s::AbstractSet) = sort!(collect(s))

```

?

---

<div class="post-metadata">

### Author: ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)
#### Post date: [April 20, 2023, 12:54pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/7 "2023-04-20T12:54:48Z")

</div>

I think this is called type piracy if you do it in your own code

If it would be part of `Base` that would work, but apparently it is not there

---

<div class="post-metadata">

### Author: ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)
#### Post date: [April 20, 2023, 12:55pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/8 "2023-04-20T12:55:51Z")

</div>

I found this related older issue [I found this related discussion, which also does not have a good answer](https://discourse.julialang.org/t/can-you-sort-a-set/47948/7)

where an alternative solution is to use PriorityQueue, but that of course does not make too much sense in this context where I want to sort the keys from a Dict

---

<div class="post-metadata">

### Author: ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)
#### Post date: [April 20, 2023, 1:03pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/9 "2023-04-20T13:03:22Z")

</div>

> [@schlichtanders](#):
>
> If it would be part of `Base` that would work

This is what I meant. I think this is very unambiguous when it appears in code, so it can easily be in Base. If any special data-structures have better ways to implement this, they can overload more specific AbstractSet implementations. I invite you to pull-request that on `base/sort.jl`

---

<div class="post-metadata">

### Author: ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)
#### Post date: [April 20, 2023, 1:05pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/10 "2023-04-20T13:05:54Z")

</div>

That would indeed be an awesome first pullrequest to Julia, especially if others can be convinced that this makes indeed sense.

I probably will only have time in about a month, but I will keep this on my todo list

---

<div class="post-metadata">

### Author: ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)
#### Post date: [April 20, 2023, 1:17pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/11 "2023-04-20T13:17:52Z")

</div>

> [@schlichtanders](#):
>
> probably this is still slower than directly constructing the vector in a sorted manner

How would that work? If you were implementing this, what container would you use as the intermediate while sorting? (`Set`s do not preserve order, so you can’t “reorder” them.) Or how would you implement a container-free `sort`? (sounds basically impossible for anything other than toy examples)

An alternative to implementing `sort(::Set)` would be to throw a more descriptive error. I agree that we should do one of these (either implement the method, or implement the error).

---

<div class="post-metadata">

### Author: ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)
#### Post date: [April 20, 2023, 1:56pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/12 "2023-04-20T13:56:37Z")

</div>

my intuition would say that

1. first constructing the vector with `collect` and then sorting inplace with `sort!` could have some overhead compared to
2. allocating an empty vector and then performing the sort on it given the values coming from the iterator of the set

but this is just my intuition, probably not worth the effort anyway, hence I really like the above solution

```julia
Base.sort(s::AbstractSet) = sort!(collect(s))

```

---

<div class="post-metadata">

### Author: ![mbaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbaz/32/17295_2.png) [@mbaz](https://discourse.julialang.org/u/mbaz)
#### Post date: [April 20, 2023, 2:04pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/13 "2023-04-20T14:04:52Z")

</div>

Just wanted to point out that [Dictionaries.jl](https://github.com/andyferris/Dictionaries.jl) are ordered and support sorting, among other nice features.

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [April 20, 2023, 2:28pm UTC](https://discourse.julialang.org/t/sort-keys-dict-a-1-b-2-throws-methoderror/97701/14 "2023-04-20T14:28:02Z")

</div>

I am not sure why you find this error prone, and it is a too small of a tidbit to be in a function in my opinion.

> [@schlichtanders](#):
>
> my intuition would say that

I think this is only relevant if you are doing this step for multiple `Set`s without keeping the sorted vector long-term (i.e., you can reuse the vector). Then the best is to:

```julia
julia> s = Set([1, 2, 3])
Set{Int64} with 3 elements:
  2
  3
  1

julia> array = Vector{Int}(undef, 3)
3-element Vector{Int64}:
 0
 0
 0

julia> array .= s
3-element Vector{Int64}:
 2
 3
 1

julia> sort!(array)
3-element Vector{Int64}:
 1
 2
 3 

```

EDIT: But this also assumes the Sets are all of the same size, otherwise `resize!(array, length(s))` is needed at each iteration.
