Guide

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}"); // 6

The 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); // false

They 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.
  • take keeps the front, skip drops the front.
  • find gives the item, position gives the index, both as Option.
  • any asks "at least one?", all asks "every one?".