jw3126
February 14, 2023, 3:58pm
1
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
aplavin
February 15, 2023, 10:17am
3
Dependency-free, infers, compiles to basically a no-op:
@generated sortkeys(nt::NamedTuple{KS}) where {KS} =
:( NamedTuple{$(Tuple(sort(collect(KS))))}(nt) )
7 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?
tbeason
February 15, 2023, 3:17pm
5
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
tbeason:
julia> NamedTuple{(:a,:b,:c)}(nt)
(a = 2, b = 1, c = 3)
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)