# Reordering NamedTuples

**URL:** <https://discourse.julialang.org/t/reordering-namedtuples/67600>\
**Category:** General Usage\
**Tags:** namedtuple\
**Created:** [September 2, 2021, 8:21pm UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600 "2021-09-02T20:21:04Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tomas\_Pevny](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomas_pevny/32/25466_2.png) [@Tomas\_Pevny](https://discourse.julialang.org/u/Tomas_Pevny)\
**Post date:** [September 2, 2021, 8:21pm UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600/1 "2021-09-02T20:21:04Z")

</div>

Dear All,

I want to ask, if anyone knows about fast (ideally typed stable) method to reorder named tuples. A  
MWE would look like

```julia
(a = 1, b = 2, c = 3)

julia> y = (c = 1, b = 2, a = 1)
(c = 1, b = 2, a = 1)

julia> map(+, x, y)
ERROR: ArgumentError: Named tuple names do not match.
Stacktrace:
 [1] map(f::Function, nt::NamedTuple{(:a, :b, :c), Tuple{Int64, Int64, Int64}}, nts::NamedTuple{(:c, :b, :a), Tuple{Int64, Int64, Int64}})
   @ Base ./namedtuple.jl:195
 [2] top-level scope
   @ REPL[34]:1

```

and I am looking for a function, call it `align`, such that

```julia
map(+, x, align(x,y)

```

would return a NamedTuple

```julia
(a = 2, b = 4, c = 4)

```

Thanks a lot for help in advance.

Tomas

---

<div class="post-metadata">

**Author:** ![genkuroki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/genkuroki/32/18030_2.png) [@genkuroki](https://discourse.julialang.org/u/genkuroki)\
**Post date:** [September 3, 2021, 7:06am UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600/2 "2021-09-03T07:06:31Z")

</div>

Is this enough?

Input:

```julia
x = (a = 1, b = 2, c = 3)
y = (c = 1, b = 2, a = 1)
z = NamedTuple(k => x[k] + y[k] for k in keys(x))

```

Output:

```julia
(a = 2, b = 4, c = 4)

```

---

<div class="post-metadata">

**Author:** ![Tomas\_Pevny](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomas_pevny/32/25466_2.png) [@Tomas\_Pevny](https://discourse.julialang.org/u/Tomas_Pevny)\
**Post date:** [September 3, 2021, 7:46am UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600/3 "2021-09-03T07:46:26Z")

</div>

I am all about type stability.

On the end, I did this.

```julia
function _reorder_nt(x::NamedTuple{NT,<:Any}, y::NamedTuple{NT,<:Any}) where {NT}
    y
end

function _reorder_nt(x::NamedTuple{NX,<:Any}, y::NamedTuple{NY,<:Any}) where {NX,NY}
    NamedTuple{NX}(map(k -> getfield(y, k), NX))
end

```

---

<div class="post-metadata">

**Author:** ![wookyoung](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wookyoung/32/157_2.png) [@wookyoung](https://discourse.julialang.org/u/wookyoung)\
**Post date:** [September 5, 2021, 4:52pm UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600/4 "2021-09-05T16:52:33Z")

</div>

well, it’s looks like `mergewith` for named tuples.  
[https://docs.julialang.org/en/v1/base/collections/#Base.mergewith](https://docs.julialang.org/en/v1/base/collections/#Base.mergewith)

I made `mergewith` for that purpose and most code taken from the `julia/base/namedtuple.jl`. you could get here (somewhat long to paste and it’s not tested a lot)  
[https://github.com/wookay/Lupin.jl/blob/master/src/mergewith.jl#L3](https://github.com/wookay/Lupin.jl/blob/master/src/mergewith.jl#L3)

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [September 5, 2021, 6:01pm UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600/5 "2021-09-05T18:01:24Z")

</div>

Just as with regular tuples, `NamedTuple`s have each type of its elements as a type parameter, i.e. the types of the elements are part of the type.

As such, an arbitrary reordering with the reordering not being known to the compiler will not be type stable.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [September 5, 2021, 6:28pm UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600/6 "2021-09-05T18:28:57Z")

</div>

I think this is pretty simple and efficient:

```julia
julia> nt1 = (; a = 1, b = 2)
(a = 1, b = 2)

julia> nt2 = (; b = 3, a = 4)
(b = 3, a = 4)

julia> NamedTuple{keys(nt1)}(nt2)
(a = 4, b = 3)

julia> @code_warntype NamedTuple{keys(nt1)}(nt2)
MethodInstance for (NamedTuple{(:a, :b)})(::NamedTuple{(:b, :a), Tuple{Int64, Int64}})
  from (NamedTuple{names})(nt::NamedTuple) where names in Base at namedtuple.jl:99
Static Parameters
  names = (:a, :b)
Arguments
  #self#::Type{NamedTuple{(:a, :b)}}
  nt::NamedTuple{(:b, :a), Tuple{Int64, Int64}}
Body::NamedTuple{(:a, :b), Tuple{Int64, Int64}}
1 ─ %1 = Core.apply_type(Base.NamedTuple, $(Expr(:static_parameter, 1)), Tuple{Int64, Int64})::Core.Const(NamedTuple{(:a, :b), Tuple{Int64, Int64}})
│ %2 = Base.getfield(nt, 2)::Int64
│ %3 = Base.getfield(nt, 1)::Int64
│ %4 = %new(%1, %2, %3)::NamedTuple{(:a, :b), Tuple{Int64, Int64}}
└── return %4

```

It’s implemented in Base with a generated function.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [September 5, 2021, 6:37pm UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600/7 "2021-09-05T18:37:23Z")

</div>

I think that will be horrible for performance if you see a lot of distinct `NamedTuple`s (i.e. arbitrary reordering) 😅

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [September 5, 2021, 6:43pm UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600/8 "2021-09-05T18:43:52Z")

</div>

Not really sure where one would get arbitrarily ordered NamedTuples from, but I agree if that’s the case, then a data structure with the order encoded in the type domain is the wrong data structure (independently of how you try to align them).

Edit: but the function I suggested _is_ type stable: if the compiler knows the types of the input NamesTuples (and thus the order), then the type of the output is known to the compiler too.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [September 5, 2021, 6:53pm UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600/9 "2021-09-05T18:53:39Z")

</div>

> [@Sukera](#):
>
> a lot of distinct

and long (because other wise combinations would soon be enumerated). But in that case, OP should use

> **[GitHub - andyferris/Dictionaries.jl: An alternative interface for...](https://github.com/andyferris/Dictionaries.jl)**
>
> An alternative interface for dictionaries in Julia, for improved productivity and performance - GitHub - andyferris/Dictionaries.jl: An alternative interface for dictionaries in Julia, for improved...

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [September 5, 2021, 7:31pm UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600/10 "2021-09-05T19:31:30Z")

</div>

> [@ericphanson](#):
>
> the function I suggested _is_ type stable: if the compiler knows the types of the input

Yep, because you’re lifting everything to the type domain via that generated function - if `nt1` were only known at runtime, it’d be unstable imo (or at least if the names (and their order?) of that tuple were only known at runtime).

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [September 5, 2021, 7:48pm UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600/11 "2021-09-05T19:48:54Z")

</div>

Right, but what I mean is the function

```julia
align(nt1, nt2) = NamedTuple{keys(nt1)}(nt2)

```

is still type stable-- if the types of the inputs are known, the types of the outputs are known. If the types of the inputs are _not_ known, then yes the compiler won’t know the types of the outputs here. So the overall procedure of {stuff producing dynamically typed `nt1` + using this `align`} would be not type stable, but the problem is coming in before the `align`.

---

<div class="post-metadata">

**Author:** ![Tomas\_Pevny](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomas_pevny/32/25466_2.png) [@Tomas\_Pevny](https://discourse.julialang.org/u/Tomas_Pevny)\
**Post date:** [September 6, 2021, 8:04am UTC](https://discourse.julialang.org/t/reordering-namedtuples/67600/12 "2021-09-06T08:04:20Z")

</div>

This exactly what I was looking for. Thanks a lot.
