# Can you filter a Dict with pairs?

Hi,

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

``````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:

``````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

You can do this:

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

2 Likes

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

1 Like

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

You can also do a comprehension

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

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:

``````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`
``````

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

``````# 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)
``````

another way to do it

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

``````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
``````