More iterator tools
These tools cover most of what loops are used for.
fold
fold takes a start value and a closure. The closure gets the running value (often called acc) and the next item, and returns the new running value.
let v = vec![1, 2, 3];let s = v.iter().fold(0, |acc, x| acc + x);println!("{s}"); // 6The start value sets the result type, so 0.0 would make it a float. To build text, start from String::new(), which makes an empty String.
take and skip
take(n) keeps the first n items. skip(n) drops the first n items and keeps the rest. If there are fewer than n items, you just get what there is.
let a: Vec<i32> = (1..=5).take(2).collect(); // [1, 2]let b: Vec<i32> = (1..=5).skip(2).collect(); // [3, 4, 5]Because iterators are lazy, take can even stop an endless range like (1..).
find and position
find returns the first item that matches, as an Option. position returns the index of the first match, also as an Option.
let v = vec![1, 4, 6];let f = v.iter().find(|x| **x > 3); // Some(4)let p = v.iter().position(|x| *x > 3); // Some(1)v.iter() gives &i32 items, and find hands its closure a reference to each item, so x is a &&i32 and needs **x. position gets the item itself, so *x is enough. Both give None when nothing matches. Both stop at the first match.
any and all
any returns true if at least one item matches. all returns true if every item matches.
let v = vec![2, 4, 5];let a = v.iter().any(|x| x % 2 == 1); // truelet b = v.iter().all(|x| x % 2 == 0); // falseThey stop early as soon as the answer is known. On an empty iterator, any is false and all is true.
Remember
fold(start, |acc, x| ...)builds one value from all items.takekeeps the front,skipdrops the front.findgives the item,positiongives the index, both asOption.anyasks "at least one?",allasks "every one?".