 # 2 filters vs 1 filter versions - Need to confirm if the 2 filter version still runs with single loop when fold comes into action

Hi there: In the code below, with lazy iterators, is there any difference in terms of looping/performance comparing 1 filter version with 2 filters version?
Need to confirm if the 2 filter version still runs with single loop when fold comes into action. Right?

Both achieve same result as shown in Output below.

fn is_odd(n: u32) -> bool {
n % 2 == 1
}

fn is_divisible_by_5(n: u32) -> bool {
n % 5 == 0
}

fn is_odd_and_divisible_by_5(n: u32) -> bool {
is_odd(n) && is_divisible_by_5(n)
}

fn main() {
let upper = 1000;

``````    // 2 filters
let filters_2_sum_of_squared_odd_numbers_divisible_by_5: u32 =
(0..).map(|n| n * n)                             // All natural numbers squared
.take_while(|&n_squared| n_squared < upper) // Below upper limit
.filter(|&n_squared| is_odd(n_squared))     // That are odd
.filter(|&n_squared| is_divisible_by_5(n_squared))     // That are divisible by 5
.fold(0, |acc, n_squared| acc + n_squared); // Sum them
println!("with 2 filters filters_2_sum_of_squared_odd_numbers_divisible_by_5: {}", filters_2_sum_of_squared_odd_numbers_divisible_by_5);

// 1 filter
let filter_1_sum_of_squared_odd_numbers_divisible_by_5: u32 =
(0..).map(|n| n * n)                             // All natural numbers squared
.take_while(|&n_squared| n_squared < upper) // Below upper limit
.filter(|&n_squared| is_odd_and_divisible_by_5(n_squared))     // That are odd and  are divisible by 5
.fold(0, |acc, n_squared| acc + n_squared); // Sum them
println!("with 1 filter filter_1_sum_of_squared_odd_numbers_divisible_by_5: {}", filter_1_sum_of_squared_odd_numbers_divisible_by_5);
}
``````

Output is

``````with 2 filters filters_2_sum_of_squared_odd_numbers_divisible_by_5: 875
with 1 filter filter_1_sum_of_squared_odd_numbers_divisible_by_5: 875``````

The rule of thumb is that every iterator consumer (`collect`, `fold`, simple `for` loop, etc.) always does one pass. Iterators usually don't store the previous states (the exception might be an explicitly written `scan`), they're discarded after being used, so it is not possible anyway to iterate over them again.

5 Likes

So that means there is no difference in using 2 filters vs 1 filter. When consumer loops, it is always 1 loop.
Thanks for confirming @Cerberuser

Also this related question answers why Rust does not need transducers

1 Like