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

As reported in the Julia documentation, 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:

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:

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.

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

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

Or write the original as

filter(x -> any(last(x) .≢ (false, nothing)), a)
1 Like

(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.)

You need to use all not any.

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

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?