Remove a field from a `NamedTuple`

Is there an easy way in base Julia to create a NamedTuple with all the fields except some particular ones? Currently I have the following, but I’m wondering if I’m missing something obvious. I’m calling it delete as it seems to do what delete! does with Dicts, but not in-place.

"""
    delete(nt::NamedTuple, fieldnames)

Remove the given fields from `nt`, returning a new `NamedTuple`
"""
function delete(nt::NamedTuple, fieldnames...)
    (; filter(p->first(p) ∉ fieldnames, collect(pairs(nt)))...)
end

The collect is necessary because apparently filter on pairs returns a Dict, which loses ordering information.

1 Like

Maybe the easiest implementation is something like

delete(nt::NamedTuple{names}, keys) where names =
    NamedTuple{filter(x -> x ∉ keys, names)}(nt)

This needs Julia 1.4 or Compat.jl imported for filter on a tuple.

There is also BangBang.delete!! that does something like this and here is how it’s implemented: https://github.com/tkf/BangBang.jl/blob/10a6a7aefe90d4e7948aab977858a3fa34a017c2/src/NoBang/base.jl#L94-L96

4 Likes

You are looking for Base.structdiff.

1 Like

That’s a good example where I wouldn’t know if I can use it or if it might change without warning.

1 Like

Good point, I opened an issue:

1 Like