Imagine you have a collection of numbers, some of which are zero. You would like to replace all the numbers up until the first zero with zeroes, and from then on make no changes to the rest of the collection.
zero_until_first_zero([1, 2, 3, 0, 1, 2, 3]) -> [0, 0, 0, 0, 1, 2, 3]
zero_until_first_zero([1, 2, 3, 4]) -> [0, 0, 0, 0]
zero_until_first_zero([0, 1, 2, 3]) -> [0, 1, 2, 3]
zero_until_first_zero([]) -> []
My friend and I came up with a couple options:
c.iter().scan(false, |found_zero, &elem| {
*found_zero = elem == 0 || *found_zero;
Some(if !*found_zero { 0 } else { elem })
}).collect()
c.iter().by_ref()
.take_while(|elem| *elem != &0).map(|_| &0)
.chain(c.iter().skip_while(|elem| *elem != &0))
.collect()
Also, a variation of the second version with map_while()
from nightly.
Finally, a straightforward but not-as-fun version that uses a for loop.
All of these seem to lack a certain elegance. I think scan()
is the right choice, but the &
's and *
's don't sit quite right for me. How would you do it in an idiomatic way?