Conditional iterator?

Is it possible to write something like this:

for (key, val) in dict if val != b
    # do something 
end

This would do the job

for (key, val) in dict 
    if val == b continue end
    # do something 
end

and this too

for (key, val) in dict if val != b
    # do something 
end end

but this looks funny.
After all you can write

[val for (key, val) in dict if val != b]
for (k, v) in dict
    v == b && continue
    # do something
end
3 Likes

If you really wanted something similar to this syntax, you could create a macro that transforms:

@when v != b, for (k, v) in dict
    # do something
end

into:

for (k, v) in dict
    if v != b
        # do something
    end
end

But in general, I think you’re better off writing it as shown by sbrombger above.

Maybe

julia> d = Dict(1=>2, 2=>3, 3=>4)
Dict{Int64,Int64} with 3 entries:
  2 => 3
  3 => 4
  1 => 2

julia> b = 3
3

julia> for (k,v) in Iterators.filter(kv -> kv.second != b, d)
           @show k, v
       end
(k, v) = (3, 4)
(k, v) = (1, 2)
2 Likes

Iterator.filter is twice as slow for large dictionaries:

julia> @benchmark it(d, 3)
BenchmarkTools.Trial: 
  memory estimate:  48 bytes
  allocs estimate:  2
  --------------
  minimum time:     1.532 s (0.00% GC)
  median time:      1.534 s (0.00% GC)
  mean time:        1.534 s (0.00% GC)
  maximum time:     1.538 s (0.00% GC)
  --------------
  samples:          4
  evals/sample:     1

julia> @benchmark noit(d, 3)
BenchmarkTools.Trial: 
  memory estimate:  16 bytes
  allocs estimate:  1
  --------------
  minimum time:     839.276 ms (0.00% GC)
  median time:      840.889 ms (0.00% GC)
  mean time:        841.129 ms (0.00% GC)
  maximum time:     843.754 ms (0.00% GC)
  --------------
  samples:          6
  evals/sample:     1
julia> function it(d, b)
           i = 0
           for (k, v) in Iterators.filter(kv -> kv.second != b, d)
               i += 1
           end
           i
       end

julia> function noit(d, b)
           i = 0
           for (k, v) in d
               v == b && continue
               i += 1
           end
           i
       end
1 Like

The title said “conditional iterator” so I assumed that an iterator was desired.

2 Likes