Home
Rust
for each Example (iter chain)
Updated Mar 24, 2023
Dot Net Perls
For each, chain. In Rust we often act upon iterators returned by the iter() function. We can use for_each to call code upon each element.
And with chain, we can elegantly combine two or more iterators. This lets us merge multiple loops into one, which can improve performance.
iter
Example. Here we introduce increment_if_four—it receives a reference to a reference to string data. It increments the count argument if the length is 4.
String Length
Part 1 We create an array of string data (values) and call for_each and increment_if_four upon each element.
Part 2 We use chain() to merge together two arrays of string data. Then we call for_each and increment_if_four on these values.
fn increment_if_four(value: &&str, count: &mut usize) { // Increment mutable argument if string length is 4. if value.len() == 4 { *count += 1; } } fn main() { // Part 1: Use for_each function on iter. let count = &mut 0; let values = ["", "1234"]; values.iter().for_each(|x| increment_if_four(x, count)); println!("INCREMENT_IF_FOUR = {count}"); // Part 2: Use for_each with chain. let values2 = ["bird", "", "dog"]; let values3 = ["red", "blue"]; values2 .iter() .chain(values3.iter()) .for_each(|x| increment_if_four(x, count)); println!("INCREMENT_IF_FOUR = {count}"); }
INCREMENT_IF_FOUR = 1 INCREMENT_IF_FOUR = 3
Chain benchmark. With for_each and chain we can combine two loops into one. Occasionally this can perform faster than two loops in Rust programs.
Version 1 This version of the code uses 2 for-loops to iterate over the 2 arrays. It checks the length of each string.
Version 2 Here we use chain and for_each to combine the two loops into one. The counts are the same in both versions.
Result The version that uses chain and for_each to merge both loops is significantly faster.
use std::time::*; fn increment_if_four(value: &&str, count: &mut usize) { if value.len() == 4 { *count += 1; } } fn main() { let values1 = ["bird", "", "dog"]; let values2 = ["red", "blue", "?"]; if let Ok(max) = "100000000".parse::<usize>() { let count1 = &mut 0; let count2 = &mut 0; // Version 1: use 2 for-loops. let t0 = Instant::now(); for _ in 0..max { for value in values1.iter() { increment_if_four(&value, count1); } for value in values2.iter() { increment_if_four(&value, count1); } } println!("{} ms", t0.elapsed().as_millis()); // Version 2: use chain with for_each. let t1 = Instant::now(); for _ in 0..max { values1 .iter() .chain(values2.iter()) .for_each(|x| increment_if_four(x, count2)); } println!("{} ms", t1.elapsed().as_millis()); println!("{count1} = {count2}"); } }
476 ms for, for 16 ms chain, for_each 200000000 = 200000000
Chain notes. Suppose our Rust program has two collections (arrays or vectors), and we want to loop over both of them. With chain, we can just write one loop, with for_each.
And This can make our Rust program more elegant, and in some cases even faster.
String Array
vec
A summary. Chain and for_each can often be used together. With for_each, we can modify a mutable argument, but we cannot return a value. This is useful in some programs.
Dot Net Perls is a collection of pages with code examples, which are updated to stay current. Programming is an art, and it can be learned from examples.
Donate to this site to help offset the costs of running the server. Sites like this will cease to exist if there is no financial support for them.
Sam Allen is passionate about computer languages, and he maintains 100% of the material available on this website. He hopes it makes the world a nicer place.
This page was last updated on Mar 24, 2023 (new example).
Home
Changes
© 2007-2025 Sam Allen