I wonder why the combination of for and if is allowed in comprehension like
nbe = sum(count(iseven,rv) for rv ∈ rvv if isodd(length(rv));init=0)
but has to be written in two separate control flows statement in loops:
#separate for and if in the loop form
nbe = 0
for rv ∈ rvv
if isodd(length(rv))
nbe += count(iseven,rv)
end
end
and can’t be written as
nbe = 0
for rv ∈ rvv if isodd(length(rv))
nbe += count(iseven,rv)
end
MWE
function test_for_if()
rvv = [[rand(Int) for s ∈ 1:rand(1:10)] for sn ∈ 1:10]
@show rvv
#separate for and if in the loop form
nbe = 0
for rv ∈ rvv
if isodd(length(rv))
nbe += count(iseven,rv)
end
end
#the comprehension for allows for for-if syntax
nbe′ = sum(count(iseven,rv) for rv ∈ rvv if isodd(length(rv));init=0)
@show nbe,nbe′
#why the following for-if syntax doesnt' apply for loops ?
# nbe′′ = 0
# for rv ∈ rvv if isodd(length(rv))
# nbe′′ += count(iseven,rv)
# end
# @show nbe,nbe′,nbe′′
return nothing
end
@LaurentPlagne, I am unsure if your question is why the language designers didn’t accommodate the syntax you are inquiring about or why you experience the issue when using the not supportedfor/if combination.
In scenarios like yours - and when comprehension is not the best pick, I like to do something like the following:
for x in 1:3
!isodd(x) && continue
@show x
end
# x = 1
# x = 3
I think @odow already sufficiently answered the question of “why”. But if you’re also looking for working alternatives, you could use Iterators.filter:
using .Iterators
nbe3 = 0
for rv in Iterators.filter(isodd ∘ length, rvv)
nbe3 += count(iseven, rv)
end
In other situations you would have to rely on anonymous functions (e.g. for rv in Iterators.filter(rv -> isodd(length(rv), rvv)) though, which to me seems more complicated than a simple if ... end or &&/||continue.