# Can you filter a Dict with pairs?

**URL:** <https://discourse.julialang.org/t/can-you-filter-a-dict-with-pairs/63685>\
**Category:** General Usage\
**Created:** [June 28, 2021, 10:27am UTC](https://discourse.julialang.org/t/can-you-filter-a-dict-with-pairs/63685 "2021-06-28T10:27:17Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![gleyland](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gleyland/32/15339_2.png) [@gleyland](https://discourse.julialang.org/u/gleyland)\
**Post date:** [June 28, 2021, 10:27am UTC](https://discourse.julialang.org/t/can-you-filter-a-dict-with-pairs/63685/1 "2021-06-28T10:27:17Z")

</div>

Hi,

I can filter a Dict with `first` and `last`:

```julia
d = Dict("a" => 1, "b" => 2, "c" => 3)
filter(e -> first(e) == "a" || last(e) == 3, d)

```

But it would be really nice if I could destructure `e` into a key and a value:

```julia
filter((k, v) -> k == "a" || v == 3, d) # doesn't seem to work
filter((k => v) -> k == "a" || v == 3, d) # nor does this.

```

Is something similar possible? Am I missing something, or are `first` and `last` the best options for `filter`ing?

Thanks!  
Geoff

---

<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:** [June 28, 2021, 10:35am UTC](https://discourse.julialang.org/t/can-you-filter-a-dict-with-pairs/63685/2 "2021-06-28T10:35:01Z")

</div>

You can do this:

> [@gleyland](#):
>
> `filter(((k, v),) -> k == "a" || v == 3, d) `

Looks a bit strange but it’s saying it’s a 1-arg function (hence the 1-tuple) whose argument should be destructured into `k` and `v`.

---

<div class="post-metadata">

**Author:** ![gleyland](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gleyland/32/15339_2.png) [@gleyland](https://discourse.julialang.org/u/gleyland)\
**Post date:** [June 28, 2021, 10:36am UTC](https://discourse.julialang.org/t/can-you-filter-a-dict-with-pairs/63685/3 "2021-06-28T10:36:42Z")

</div>

Thanks! It does look strange, but your explanation makes perfect sense!

---

<div class="post-metadata">

**Author:** ![gleyland](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gleyland/32/15339_2.png) [@gleyland](https://discourse.julialang.org/u/gleyland)\
**Post date:** [June 28, 2021, 10:42am UTC](https://discourse.julialang.org/t/can-you-filter-a-dict-with-pairs/63685/4 "2021-06-28T10:42:20Z")

</div>

Oh, and `filter(a) do (k, v) k == 'a" || v == 3 end` also works, and is almost clearer.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [June 28, 2021, 10:48am UTC](https://discourse.julialang.org/t/can-you-filter-a-dict-with-pairs/63685/5 "2021-06-28T10:48:51Z")

</div>

You can also do a comprehension

```julia
Dict(k=>v for (k, v) in d if k == "a" || v == 3)

```

---

<div class="post-metadata">

**Author:** ![gleyland](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gleyland/32/15339_2.png) [@gleyland](https://discourse.julialang.org/u/gleyland)\
**Post date:** [June 28, 2021, 10:56am UTC](https://discourse.julialang.org/t/can-you-filter-a-dict-with-pairs/63685/6 "2021-06-28T10:56:53Z")

</div>

Oh, thanks. I should have mentioned comprehensions. It’s really just a case of thinking that `filter` might convey the intent more clearly than a comprehension, and then finding that the syntax didn’t work as cleanly.

In fact, I’m trying to filter a Dict with a Set of keys. It would be really nice if an intersection worked:

```julia
d = Dict("a" => 1, "b" => 2, "c" => 3)
s = Set(["a", "c"])
d ∩ s # doesn't work - fair enough because it's trying to match the pairs in `d`

```

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [June 28, 2021, 1:03pm UTC](https://discourse.julialang.org/t/can-you-filter-a-dict-with-pairs/63685/7 "2021-06-28T13:03:55Z")

</div>

While that would indeed indeed nice notation for it, you can do that as well with a comprehension

```julia
# if all of the elements of s are definitely keys of d
Dict(k => d[k] for k in s)

# if not
Dict(k => d[k] for k in s if haskey(d, k))

# also possible with filter, but it's slower in general because it requires more inclusion checks. 
filter(e -> first(e) ∈ s, d)

```

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [June 28, 2021, 1:04pm UTC](https://discourse.julialang.org/t/can-you-filter-a-dict-with-pairs/63685/8 "2021-06-28T13:04:17Z")

</div>

> [@gleyland](#):
>
> ```julia
> filter(d) do e
> any(collect(e) .== ("a", 3))
> end
> 
> ```

another way to do it

---

<div class="post-metadata">

**Author:** ![yha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yha/32/3502_2.png) [@yha](https://discourse.julialang.org/u/yha)\
**Post date:** [June 28, 2021, 1:59pm UTC](https://discourse.julialang.org/t/can-you-filter-a-dict-with-pairs/63685/9 "2021-06-28T13:59:36Z")

</div>

You can also convert a two-argument function taking key and value to a single argument function using `Base.splat`

```julia
julia> kvfilter(f,d) = filter(Base.splat(f), d);

julia> kvfilter((k,v) -> v>1, Dict("a" => 1, "b" => 2, "c" => 3))
Dict{String, Int64} with 2 entries:
  "c" => 3
  "b" => 2

```
