# Conditionally repeat iterator item

I'm trying to figure out how to count an iterator item twice if some condition is met, but only once otherwise.

``````dbg!((1..=20).zip((1..=20).rev())
.filter(|(a,b)| a % 2 == 0 || b % 3 == 0)
.inspect(|ab| println!("{:?}", ab))
.count());
``````

Yields a count of 13 for the items

``````(2, 19)
(3, 18)
(4, 17)
(6, 15)
(8, 13)
(9, 12)
(10, 11)
(12, 9)
(14, 7)
(15, 6)
(16, 5)
(18, 3)
(20, 1)
``````

but I would like to be able to count the following tuples twice since both values satisfy the condition

``````(6, 15)
(12, 9)
(18, 3)

``````

and end up with a count of 16. Any suggestions for how to accomplish this? I'm trying to avoid iterating separately and then adding the counts together.

You could instead map to a score and sum that.

1 Like

Thanks! That does the trick, though the clunky way I've done it is inelegant it gives me the right idea.

``````(1..=20).zip((1..=20).rev())
.filter(|(a,b)| a % 2 == 0 || b % 3 == 0)
.map(|(a,b)| if a % 2 == 0 && b % 3 == 0 { 2 } else { 1 })
.inspect(|ab| println!("{:?}", ab))
.fold(0, |mut acc, score| acc + score)
``````

But then why are you filtering in this case at all? It completely defeats the purpose of using the "score". You could just assign a score of 0 when neither condition is satisfied, and you don't need the `if-else` either:

``````let count = (1..=20).zip((1..=20).rev())
.map(|(a, b)| (a % 2 == 0) as usize + (b % 3 == 0) as usize)
.sum::<usize>();

println!("{}", count); // 16
``````

You are right of course. I didn't put much thought into it after realizing I had put out an XY problem. The example code was not really indicative of the problem I was actually trying to solve, just of the flawed method I was trying to use to solve it.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.