# Possibility to check \`∈\` and \`∉\` in the \`===\` sense

**URL:** <https://discourse.julialang.org/t/possibility-to-check-and-in-the-sense/12630>\
**Category:** Internals & Design\
**Created:** [July 24, 2018, 7:50am UTC](https://discourse.julialang.org/t/possibility-to-check-and-in-the-sense/12630 "2018-07-24T07:50:03Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![lucatrv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucatrv/32/5650_2.png) [@lucatrv](https://discourse.julialang.org/u/lucatrv)\
**Post date:** [July 24, 2018, 7:50am UTC](https://discourse.julialang.org/t/possibility-to-check-and-in-the-sense/12630/1 "2018-07-24T07:50:03Z")

</div>

As reported in the [Julia documentation](https://docs.julialang.org/en/latest/base/collections/#Base.in), the `in`, `∈`, `∋`, `∉`, `∌` functions “determine whether an item is in the given collection, in the sense that it is `==` to one of the values generated by iterating over the collection”.

I need to filter out all entries of a dictionary with value equal to either `nothing` or `false`. The following command filters out also entries with value equal to `0`, which instead I need to keep:

```julia
a = Dict("a"=>1, "b"=>0, "c"=>false, "d"=>2, "e"=>"test", "f"=>nothing)
filter(x -> x.second ∉ (false, nothing), a)

```

This is a possible workaround:

```julia
filter(x -> x.second !== false && x.second !== nothing, a)

```

but in my opinion it would be useful to define analogous functions working in the `===` sense, which could for instance be named `in=`, `∈=`, `∋=`, `∉=`, `∌=`. Their documentation would also better clarify how `in`, `∈`, `∋`, `∉`, `∌` behave in these cases, helping to avoid similar bugs.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [July 24, 2018, 2:00pm UTC](https://discourse.julialang.org/t/possibility-to-check-and-in-the-sense/12630/2 "2018-07-24T14:00:03Z")

</div>

You could always define this if you want (in 0.7):

```julia
∈₌(x, collection) = any(y -> x === y, collection)

```

---

<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:** [July 24, 2018, 2:11pm UTC](https://discourse.julialang.org/t/possibility-to-check-and-in-the-sense/12630/3 "2018-07-24T14:11:01Z")

</div>

Or write the original as

```julia
filter(x -> any(last(x) .≢ (false, nothing)), a)

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [July 24, 2018, 3:59pm UTC](https://discourse.julialang.org/t/possibility-to-check-and-in-the-sense/12630/4 "2018-07-24T15:59:12Z")

</div>

> [@Tamas\_Papp](#):
>
> `filter(x -> any(last(x) .≢ (false, nothing)), a)`

(That allocates a temporary array (to pass to `any` ) for every element `x` of `a`, which is pretty inefficient for large `a`. Though it’s not clear that the original poster cares about performance here.)

---

<div class="post-metadata">

**Author:** ![Liso](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@Liso](https://discourse.julialang.org/u/Liso)\
**Post date:** [July 24, 2018, 5:13pm UTC](https://discourse.julialang.org/t/possibility-to-check-and-in-the-sense/12630/5 "2018-07-24T17:13:25Z")

</div>

You need to use `all` not `any`.

---

<div class="post-metadata">

**Author:** ![Liso](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@Liso](https://discourse.julialang.org/u/Liso)\
**Post date:** [July 24, 2018, 5:20pm UTC](https://discourse.julialang.org/t/possibility-to-check-and-in-the-sense/12630/6 "2018-07-24T17:20:26Z")

</div>

It is really interesting that original poster workaround seems to be 5 times faster than your solution!

```julia
0.7.0-beta2.83> t1() = filter(x -> x.second !== false && x.second !== nothing, a);
0.7.0-beta2.83> t2() = filter(x -> all(last(x) .≢ (false, nothing)), a);
0.7.0-beta2.83> t3() = let out=(false, nothing); filter(x -> all(last(x) .≢ out), a) end;
0.7.0-beta2.83> t4() = let out=[false, nothing]; filter(x -> all(last(x) .≢ out), a) end;
0.7.0-beta2.83> t5() = filter(x -> x ∈₌(false, nothing), a);

0.7.0-beta2.83> @btime t1();
  351.200 ns (4 allocations: 608 bytes)

0.7.0-beta2.83> @btime t2();
  4.107 μs (30 allocations: 1.21 KiB)

0.7.0-beta2.83> @btime t2();
  4.032 μs (30 allocations: 1.21 KiB)

0.7.0-beta2.83> @btime t3();
  4.030 μs (37 allocations: 1.32 KiB)

0.7.0-beta2.83> @btime t4();
  12.642 μs (46 allocations: 27.10 KiB)

0.7.0-beta2.83> @btime t5();
  1.887 μs (10 allocations: 704 bytes)

```

I am surprised that `let` did not help. What did I do wrong?

BTW I would expect that compiler optimize allocating in Tamas’s solution. Maybe in future version of julia?
