Sort keys of NamedTuple

I would like to sort a NamedTuple alphabetically by its keys. For instance:

(b=1, a=2, c=3) ---> (a=2, b=1, c=3)
(a=1, c=2, b=3) ---> (a=1, b=3, c=2)

I am pretty sure such functionality already exists, where to look for it? Bonus points if the solutions infers.

Not sure if this is reasonable:

using TupleTools
nt = (b=1, a=2, c=3)
NamedTuple{TupleTools.sort(keys(nt))}(nt)
# result:
(a = 2, b = 1, c = 3)
3 Likes

Dependency-free, infers, compiles to basically a no-op:

@generated sortkeys(nt::NamedTuple{KS}) where {KS} =
    :( NamedTuple{$(Tuple(sort(collect(KS))))}(nt) )
6 Likes

could you please explain how it works in some detail?
For example, where does it happen that in addition to sorting the keys the values are also correspondingly sorted?

Both of those solutions work in the same manner.

julia> nt = (b=1, a=2, c=3)
(b = 1, a = 2, c = 3)

julia> typeof(nt)
NamedTuple{(:b, :a, :c), Tuple{Int64, Int64, Int64}}

julia> NamedTuple{(:a,:b,:c)}(nt)
(a = 2, b = 1, c = 3)

The last line works because of (from ? NamedTuple)

NamedTuple{names}(nt::NamedTuple)

  Construct a named tuple by selecting fields in names (a tuple of Symbols) from another named tuple.
1 Like

Very interesting.
Now I can understand at least part of @aplavin solution
Seems to work for some of the fields as well.

 NamedTuple{(:c,:b)}(nt)