# Remove a field from a \`NamedTuple\`

**URL:** <https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664>\
**Category:** General Usage\
**Created:** [February 15, 2020, 5:16am UTC](https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664 "2020-02-15T05:16:22Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)\
**Post date:** [February 15, 2020, 5:16am UTC](https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664/1 "2020-02-15T05:16:22Z")

</div>

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 `Dict`s, but not in-place.

```julia
"""
    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.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [February 15, 2020, 5:52am UTC](https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664/2 "2020-02-15T05:52:57Z")

</div>

Maybe the easiest implementation is something like

```julia
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!!`](https://tkf.github.io/BangBang.jl/dev/#BangBang.delete!!-Tuple%7BAny,Any%7D) that does something like this and here is how it’s implemented: [BangBang.jl/base.jl at 10a6a7aefe90d4e7948aab977858a3fa34a017c2 · JuliaFolds/BangBang.jl · GitHub](https://github.com/tkf/BangBang.jl/blob/10a6a7aefe90d4e7948aab977858a3fa34a017c2/src/NoBang/base.jl#L94-L96)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 15, 2020, 3:03pm UTC](https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664/3 "2020-02-15T15:03:00Z")

</div>

You are looking for `Base.structdiff`.

---

<div class="post-metadata">

**Author:** ![laborg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laborg/32/5474_2.png) [@laborg](https://discourse.julialang.org/u/laborg)\
**Post date:** [February 15, 2020, 3:30pm UTC](https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664/4 "2020-02-15T15:30:37Z")

</div>

> [@Tamas\_Papp](#):
>
> `Base.structdiff` .

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

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 15, 2020, 3:48pm UTC](https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664/5 "2020-02-15T15:48:10Z")

</div>

Good point, I opened an issue:

[https://github.com/JuliaLang/julia/issues/34772](https://github.com/JuliaLang/julia/issues/34772)

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [August 12, 2024, 8:09am UTC](https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664/6 "2024-08-12T08:09:24Z")

</div>

So, what is the solution today (2024-08-12)?

> [@Tamas\_Papp](#):
>
> [export Base.structdiff · Issue #34772 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/34772)

Is `Base.structdiff` still the recommended way?

* * *

I naïvely thought that deleting a key-value pair from a NamedTuple is so analogous to doing so from a Dict that `delete()` is the most appropriate name for this operation. But apparently, it’s not. Why?

I’ve been also surprised that there is no `delete()` for Dict whereas there is `delete!()`. I thought it would be `nt2 = delete(nt1, keytodelete)` for a NamedTuple. . . .

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 12, 2024, 8:30am UTC](https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664/7 "2024-08-12T08:30:22Z")

</div>

> [@ryofurue](#):
>
> But apparently, it’s not. Why?

For `NamedTuple`s, the fields are part of the type, so they have to be provided in a way that can be inferred.

`delete` could work with constant folding though I guess.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [August 12, 2024, 9:05am UTC](https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664/8 "2024-08-12T09:05:20Z")

</div>

> <https://github.com/JuliaLang/julia/pull/55270>
>
> from #27725
> 
> We should possibly add some more methods to this and export/publi…c it, but that can be decided separately.

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [August 14, 2024, 2:03pm UTC](https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664/9 "2024-08-14T14:03:17Z")

</div>

> [@Tamas\_Papp](#):
>
> For `NamedTuple`s, the fields are part of the type, so they have to be provided in a way that can be inferred.

I think I understand the issue. `delete!(dict, . . .)` works by modifying the first object, but `delete!(nt, . . .)` cannot, because deleting an element would change the type of the object, which cannot be an in-place modification.

> [@](#):
>
> `delete` could work with constant folding though I guess.

Along these lines?

```julia
delete(nt, sym) = Base.structdiff(nt, NamedTuple{(sym,)}((nothing,)))

```

(I don’t know well how to construct a NamedTuple using the constructor.)

If this `delete()` is a good idea, I’d also like to see it for Dict:

```julia
newdict = delete(dict, keytodelete)

```

Sometime ago, I had to first copy a Dict before deleting some of its elements.

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [August 14, 2024, 2:03pm UTC](https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664/10 "2024-08-14T14:03:59Z")

</div>

Great!

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 14, 2024, 2:31pm UTC](https://discourse.julialang.org/t/remove-a-field-from-a-namedtuple/34664/11 "2024-08-14T14:31:06Z")

</div>

> [@ryofurue](#):
>
> Along these lines?

See the PR linked by @nsajko, especially the aggressive constant propagation.
