Debug School

rakesh kumar
rakesh kumar

Posted on

Different kinds of iterators in Rust

Why iterators are needed (Theory)
Different kinds of iterators in Rust
Basic programming example of iterator
Rust examples (iter with many data types)
Summary

Why iterators are needed (Theory)

Iterators solve these problems:

Avoid manual for (i=0...) indexing bugs

Make code cleaner with map / filter / fold

Lazy processing (doesn’t compute until needed) → better performance

Works uniformly for arrays, vectors, ranges, strings, hashmaps, custom collections

Different kinds of iterators in Rust

1) iter() — read-only iterator (borrow)

Gives &T items

Use when you only need to read

2) iter_mut() — mutable iterator (mut borrow)

Gives &mut T items

Use when you want to modify items in-place

3) into_iter() — owning iterator (moves values)

Gives T items (ownership moves out)

Use when you want to consume the collection

For Vec<T>:
iter() → &T
iter_mut() → &mut T
into_iter() → T
Enter fullscreen mode Exit fullscreen mode

4) Range iterators: 1..5, 1..=5

No collection required

Great for loops and generating sequences

5) Iterator adapters (lazy transformations)

These don’t run immediately; they build a pipeline:

map, filter, take, skip, enumerate, zip, flat_map
They run only when consumed by:

collect, for, sum, count, fold, any, all

6) Consumer (terminal) operations

collect() → build Vec, HashMap, etc.

sum(), count(), fold(), find()
Enter fullscreen mode Exit fullscreen mode

7) Custom iterator (implement Iterator trait)

You can make your own sequences like counters, Fibonacci, pagination iterators.

Full Rust code (covers all iterator kinds)

use std::collections::HashMap;

// -------- Custom Iterator (7) --------
struct Counter {
    current: i32,
    end: i32,
}

impl Counter {
    fn new(end: i32) -> Self {
        Self { current: 0, end }
    }
}

impl Iterator for Counter {
    type Item = i32;

    fn next(&mut self) -> Option<Self::Item> {
        if self.current >= self.end {
            None
        } else {
            self.current += 1;
            Some(self.current)
        }
    }
}

fn main() {
    let mut nums = vec![10, 20, 30];

    println!("--- 1) iter() (read-only) ---");
    for x in nums.iter() {
        println!("read: {}", x); // x is &i32
    }

    println!("\n--- 2) iter_mut() (modify in-place) ---");
    for x in nums.iter_mut() {
        *x += 5; // x is &mut i32, so dereference and update
    }
    println!("after iter_mut: {:?}", nums);

    println!("\n--- 3) into_iter() (takes ownership) ---");
    let nums2 = vec![1, 2, 3];
    for x in nums2.into_iter() {
        println!("owned: {}", x); // x is i32 (moved out)
    }
    // nums2 is not usable now

    println!("\n--- 4) Range iterator ---");
    let range_vals: Vec<i32> = (1..=5).collect();
    println!("(1..=5).collect() => {:?}", range_vals);

    println!("\n--- 5) Adapters: map + filter + enumerate + take ---");
    let data = vec![1, 2, 3, 4, 5, 6];

    let pipeline: Vec<String> = data
        .iter()
        .filter(|&&x| x % 2 == 0)           // keep even
        .map(|&x| x * 10)                   // multiply
        .enumerate()                        // add index
        .take(2)                            // only first 2 items
        .map(|(i, v)| format!("i={} v={}", i, v))
        .collect();

    println!("pipeline result => {:?}", pipeline);

    println!("\n--- 6) Consumers: sum, count, fold, find ---");
    let sum: i32 = data.iter().sum();
    let count = data.iter().filter(|&&x| x > 3).count();
    let product = data.iter().fold(1, |acc, &x| acc * x);
    let first_gt_4 = data.iter().find(|&&x| x > 4);

    println!("sum = {}", sum);
    println!("count(x > 3) = {}", count);
    println!("product (fold) = {}", product);
    println!("first > 4 = {:?}", first_gt_4);

    println!("\n--- Iterator on HashMap (keys/values) ---");
    let mut map = HashMap::new();
    map.insert("a", 10);
    map.insert("b", 20);

    for (k, v) in map.iter() {
        println!("{} => {}", k, v);
    }

    println!("\n--- 7) Custom Iterator ---");
    let custom_vals: Vec<i32> = Counter::new(5).collect();
    println!("Counter::new(5) => {:?}", custom_vals);
}
Enter fullscreen mode Exit fullscreen mode

Output (Rust)

--- 1) iter() (read-only) ---
read: 10
read: 20
read: 30

--- 2) iter_mut() (modify in-place) ---
after iter_mut: [15, 25, 35]

--- 3) into_iter() (takes ownership) ---
owned: 1
owned: 2
owned: 3

--- 4) Range iterator ---
(1..=5).collect() => [1, 2, 3, 4, 5]

--- 5) Adapters: map + filter + enumerate + take ---
pipeline result => ["i=0 v=20", "i=1 v=40"]

--- 6) Consumers: sum, count, fold, find ---
sum = 21
count(x > 3) = 3
product (fold) = 720
first > 4 = Some(5)

--- Iterator on HashMap (keys/values) ---
a => 10
b => 20

--- 7) Custom Iterator ---
Counter::new(5) => [1, 2, 3, 4, 5]
Enter fullscreen mode Exit fullscreen mode

Java comparison (Iterators + Streams)
Java equivalents

Rust iter() ≈ Java enhanced for-loop (read-only idea)

Rust iter_mut() ≈ loop with set(i, ...) or ListIterator

Rust into_iter() ≈ not direct; Java usually keeps references, but you can “consume” logically by not reusing

Rust iterator adapters ≈ Java Stream pipeline (filter/map/limit)

Rust custom iterator ≈ Java Iterator implementation

Rust fold() ≈ Java reduce()

Full Java code (similar features)

import java.util.*;
import java.util.stream.Collectors;

public class Main {

    // Custom iterator like Rust Counter
    static class Counter implements Iterator<Integer> {
        private int current = 0;
        private final int end;

        Counter(int end) { this.end = end; }

        @Override
        public boolean hasNext() {
            return current < end;
        }

        @Override
        public Integer next() {
            current++;
            return current;
        }
    }

    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>(Arrays.asList(10, 20, 30));

        System.out.println("--- 1) Read-only iteration ---");
        for (Integer x : nums) {
            System.out.println("read: " + x);
        }

        System.out.println("\n--- 2) Modify in-place (like iter_mut) ---");
        for (int i = 0; i < nums.size(); i++) {
            nums.set(i, nums.get(i) + 5);
        }
        System.out.println("after modify: " + nums);

        System.out.println("\n--- 4) Range (like Rust range iterator) ---");
        List<Integer> rangeVals = new ArrayList<>();
        for (int i = 1; i <= 5; i++) rangeVals.add(i);
        System.out.println("1..=5 => " + rangeVals);

        System.out.println("\n--- 5) Stream adapters: filter + map + limit ---");
        List<Integer> data = Arrays.asList(1,2,3,4,5,6);

        List<String> pipeline = data.stream()
                .filter(x -> x % 2 == 0)
                .map(x -> x * 10)
                .limit(2)
                .map(v -> "v=" + v)
                .collect(Collectors.toList());

        System.out.println("pipeline result => " + pipeline);

        System.out.println("\n--- 6) Consumers: sum, count, reduce, findFirst ---");
        int sum = data.stream().mapToInt(x -> x).sum();
        long count = data.stream().filter(x -> x > 3).count();
        int product = data.stream().reduce(1, (acc, x) -> acc * x);
        Optional<Integer> firstGt4 = data.stream().filter(x -> x > 4).findFirst();

        System.out.println("sum = " + sum);
        System.out.println("count(x > 3) = " + count);
        System.out.println("product (reduce) = " + product);
        System.out.println("first > 4 = " + firstGt4);

        System.out.println("\n--- HashMap iteration ---");
        Map<String, Integer> map = new HashMap<>();
        map.put("a", 10);
        map.put("b", 20);

        for (Map.Entry<String, Integer> e : map.entrySet()) {
            System.out.println(e.getKey() + " => " + e.getValue());
        }

        System.out.println("\n--- Custom Iterator ---");
        Counter c = new Counter(5);
        List<Integer> customVals = new ArrayList<>();
        while (c.hasNext()) {
            customVals.add(c.next());
        }
        System.out.println("Counter(5) => " + customVals);
    }
}
Enter fullscreen mode Exit fullscreen mode

Output (Java)

--- 1) Read-only iteration ---
read: 10
read: 20
read: 30

--- 2) Modify in-place (like iter_mut) ---
after modify: [15, 25, 35]

--- 4) Range (like Rust range iterator) ---
1..=5 => [1, 2, 3, 4, 5]

--- 5) Stream adapters: filter + map + limit ---
pipeline result => [v=20, v=40]

--- 6) Consumers: sum, count, reduce, findFirst ---
sum = 21
count(x > 3) = 3
product (reduce) = 720
first > 4 = Optional[5]

--- HashMap iteration ---
a => 10
b => 20

--- Custom Iterator ---
Counter(5) => [1, 2, 3, 4, 5]
Enter fullscreen mode Exit fullscreen mode

Basic programming example of iterator

Programming example of Iterator type

Basic iter() + print

fn main() {
    let v = vec![10, 20, 30];
    for x in v.iter() {
        print!("{x} ");
    }
    println!();
}
Enter fullscreen mode Exit fullscreen mode

Output


10 20 30
Enter fullscreen mode Exit fullscreen mode

2) iter_mut() modify in place

fn main() {
    let mut v = vec![1, 2, 3];
    for x in v.iter_mut() {
        *x *= 10;
    }
    println!("{:?}", v);
}
Enter fullscreen mode Exit fullscreen mode

Output

[10, 20, 30]
Enter fullscreen mode Exit fullscreen mode

3) into_iter() takes ownership

fn main() {
    let v = vec!["a".to_string(), "b".to_string()];
    for s in v.into_iter() {
        println!("{s}");
    }
}
Enter fullscreen mode Exit fullscreen mode

Output

a
b

Enter fullscreen mode Exit fullscreen mode

4) map()

fn main() {
    let v = vec![1, 2, 3];
    let out: Vec<i32> = v.iter().map(|x| x * 2).collect();
    println!("{:?}", out);
}
Enter fullscreen mode Exit fullscreen mode

Output

[2, 4, 6]
Enter fullscreen mode Exit fullscreen mode

5) filter()

fn main() {
    let v = vec![1, 2, 3, 4, 5, 6];
    let evens: Vec<i32> = v.into_iter().filter(|x| x % 2 == 0).collect();
    println!("{:?}", evens);
}

Enter fullscreen mode Exit fullscreen mode

Output

[2, 4, 6]
Enter fullscreen mode Exit fullscreen mode

6) filter_map() (parse only valid numbers)

fn main() {
    let items = vec!["10", "x", "20", "y", "30"];
    let nums: Vec<i32> = items.into_iter().filter_map(|s| s.parse().ok()).collect();
    println!("{:?}", nums);
}
Enter fullscreen mode Exit fullscreen mode

Output

[10, 20, 30]
Enter fullscreen mode Exit fullscreen mode

7)enumerate()

fn main() {
    let v = vec!["aa", "bb", "cc"];
    for (i, val) in v.iter().enumerate() {
        println!("{i}: {val}");
    }
}
Enter fullscreen mode Exit fullscreen mode

Output

0: aa
1: bb
2: cc
Enter fullscreen mode Exit fullscreen mode

8) take()

fn main() {
    let v = vec![1, 2, 3, 4, 5];
    let first3: Vec<i32> = v.into_iter().take(3).collect();
    println!("{:?}", first3);
}

Enter fullscreen mode Exit fullscreen mode

Output

[1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

9) skip()

fn main() {
    let v = vec![1, 2, 3, 4, 5];
    let after2: Vec<i32> = v.into_iter().skip(2).collect();
    println!("{:?}", after2);
}
Enter fullscreen mode Exit fullscreen mode

Output

[3, 4, 5]
Enter fullscreen mode Exit fullscreen mode

10) take_while()

fn main() {
    let v = vec![1, 2, 3, 2, 1];
    let out: Vec<i32> = v.into_iter().take_while(|x| *x < 3).collect();
    println!("{:?}", out);
}
Enter fullscreen mode Exit fullscreen mode

Output

[1, 2]
Enter fullscreen mode Exit fullscreen mode

11) skip_while()

fn main() {
    let v = vec![1, 1, 2, 3, 1];
    let out: Vec<i32> = v.into_iter().skip_while(|x| *x == 1).collect();
    println!("{:?}", out);
}
Enter fullscreen mode Exit fullscreen mode

Output

[2, 3, 1]
Enter fullscreen mode Exit fullscreen mode

12) any() / all()

fn main() {
    let v = vec![2, 4, 6];
    println!("{}", v.iter().any(|x| x % 2 != 0));
    println!("{}", v.iter().all(|x| x % 2 == 0));
}

Enter fullscreen mode Exit fullscreen mode

Output

false
true
Enter fullscreen mode Exit fullscreen mode

13) find()

fn main() {
    let v = vec![10, 15, 20, 25];
    let ans = v.iter().find(|&&x| x > 18);
    println!("{:?}", ans);
}
Enter fullscreen mode Exit fullscreen mode

Output

Some(20)

Enter fullscreen mode Exit fullscreen mode

14) position()

fn main() {
    let v = vec![5, 7, 9, 11];
    let idx = v.iter().position(|&x| x == 9);
    println!("{:?}", idx);
}
Enter fullscreen mode Exit fullscreen mode

Output


Some(2)
Enter fullscreen mode Exit fullscreen mode

15) fold() (sum)

fn main() {
    let v = vec![1, 2, 3, 4];
    let sum = v.iter().fold(0, |acc, x| acc + x);
    println!("{sum}");
}
Enter fullscreen mode Exit fullscreen mode

Output

10
Enter fullscreen mode Exit fullscreen mode

16) reduce() (max)

fn main() {
    let v = vec![3, 9, 2, 7];
    let mx = v.into_iter().reduce(|a, b| a.max(b));
    println!("{:?}", mx);
}
Enter fullscreen mode Exit fullscreen mode

Output

Some(9)
Enter fullscreen mode Exit fullscreen mode

17) zip() (pair elements)

fn main() {
    let a = vec![1, 2, 3];
    let b = vec![10, 20, 30];
    let out: Vec<i32> = a.into_iter().zip(b.into_iter()).map(|(x, y)| x + y).collect();
    println!("{:?}", out);
}
Enter fullscreen mode Exit fullscreen mode

Output

[11, 22, 33]
Enter fullscreen mode Exit fullscreen mode

18) chain() (join two iterators)

fn main() {
    let a = vec![1, 2];
    let b = vec![3, 4];
    let out: Vec<i32> = a.into_iter().chain(b.into_iter()).collect();
    println!("{:?}", out);
}
Enter fullscreen mode Exit fullscreen mode

Output

[1, 2, 3, 4]

Enter fullscreen mode Exit fullscreen mode

19) flat_map() (flatten nested lists)

fn main() {
    let v = vec![vec![1, 2], vec![3], vec![4, 5]];
    let out: Vec<i32> = v.into_iter().flat_map(|inner| inner.into_iter()).collect();
    println!("{:?}", out);
}
Enter fullscreen mode Exit fullscreen mode

Output

[1, 2, 3, 4, 5]
Enter fullscreen mode Exit fullscreen mode

20) collect() into HashMap

use std::collections::HashMap;

fn main() {
    let items = vec![("a", 1), ("b", 2), ("c", 3)];
    let map: HashMap<&str, i32> = items.into_iter().collect();
    println!("{:?}", map.get("b"));
}

Enter fullscreen mode Exit fullscreen mode

Output

Some(2)
Enter fullscreen mode Exit fullscreen mode

Rust examples (iter with many data types)

use std::collections::HashMap;

fn main() {
    // ---------------- String (chars iterator) ----------------
    println!("--- String iter (chars) ---");
    let s = String::from("Ashwani");
    for ch in s.chars() {
        print!("{} ", ch);
    }
    println!();

    // bytes iterator
    println!("--- String iter (bytes) ---");
    let s2 = "Hi🙂"; // contains emoji (UTF-8)
    for b in s2.bytes() {
        print!("{} ", b);
    }
    println!("\n");

    // ---------------- Array ----------------
    println!("--- Array iter() ---");
    let arr = [10, 20, 30, 40];
    for x in arr.iter() {
        print!("{} ", x);
    }
    println!();

    // array with enumerate
    println!("--- Array iter().enumerate() ---");
    for (i, x) in arr.iter().enumerate() {
        println!("index={} value={}", i, x);
    }
    println!();

    // ---------------- Vec ----------------
    println!("--- Vec iter() (read-only) ---");
    let mut v = vec![1, 2, 3, 4, 5];
    for x in v.iter() {
        print!("{} ", x);
    }
    println!();

    println!("--- Vec iter_mut() (modify) ---");
    for x in v.iter_mut() {
        *x *= 10;
    }
    println!("after iter_mut => {:?}", v);

    println!("--- Vec into_iter() (move/own) ---");
    let v2 = vec!["a", "b", "c"];
    for item in v2.into_iter() {
        print!("{} ", item);
    }
    println!("\n");

    // ---------------- List-like (Rust doesn't have built-in List, uses Vec / LinkedList) ----------------
    println!("--- LinkedList iter() (list-like) ---");
    let mut list = std::collections::LinkedList::new();
    list.push_back(100);
    list.push_back(200);
    list.push_back(300);

    for x in list.iter() {
        print!("{} ", x);
    }
    println!("\n");

    // ---------------- Dict (HashMap) ----------------
    println!("--- HashMap iter() (dict) ---");
    let mut map = HashMap::new();
    map.insert("apple", 3);
    map.insert("banana", 5);

    for (k, v) in map.iter() {
        println!("{} => {}", k, v);
    }
    println!();

    println!("--- HashMap keys() ---");
    for k in map.keys() {
        print!("{} ", k);
    }
    println!();

    println!("--- HashMap values() ---");
    for v in map.values() {
        print!("{} ", v);
    }
    println!("\n");

    // ---------------- Tuple ----------------
    // Tuple itself doesn't have iter() because it's not a collection.
    // But you can destructure it or convert to an array if same type.
    println!("--- Tuple destructuring ---");
    let t = (10, "hello", true);
    let (a, b, c) = t;
    println!("a={}, b={}, c={}", a, b, c);

    println!("--- Tuple -> array (same type tuple) + iter() ---");
    let t2 = (7, 8, 9); // all i32
    let arr_from_tuple = [t2.0, t2.1, t2.2];
    for x in arr_from_tuple.iter() {
        print!("{} ", x);
    }
    println!("\n");

    // ---------------- Bonus: iterator pipeline example ----------------
    println!("--- Pipeline on Vec ---");
    let nums = vec![1, 2, 3, 4, 5, 6];
    let result: Vec<i32> = nums
        .iter()
        .filter(|&&x| x % 2 == 0)
        .map(|&x| x * 100)
        .collect();
    println!("even * 100 => {:?}", result);
}
Enter fullscreen mode Exit fullscreen mode

Output (Rust)

--- String iter (chars) ---
A s h w a n i 
--- String iter (bytes) ---
72 105 240 159 153 130 

--- Array iter() ---
10 20 30 40 
--- Array iter().enumerate() ---
index=0 value=10
index=1 value=20
index=2 value=30
index=3 value=40

--- Vec iter() (read-only) ---
1 2 3 4 5 
--- Vec iter_mut() (modify) ---
after iter_mut => [10, 20, 30, 40, 50]
--- Vec into_iter() (move/own) ---
a b c 

--- LinkedList iter() (list-like) ---
100 200 300 

--- HashMap iter() (dict) ---
apple => 3
banana => 5

--- HashMap keys() ---
apple banana 
--- HashMap values() ---
3 5 

--- Tuple destructuring ---
a=10, b=hello, c=true
--- Tuple -> array (same type tuple) + iter() ---
7 8 9 

--- Pipeline on Vec ---
even * 100 => [200, 400, 600]
Enter fullscreen mode Exit fullscreen mode

Java comparison (String, array, List, Map, “tuple”)

Java doesn’t have built-in tuple, but we can use a small class.

import java.util.*;

public class Main {

    static class Tuple3<A, B, C> {
        A a; B b; C c;
        Tuple3(A a, B b, C c) { this.a = a; this.b = b; this.c = c; }
    }

    public static void main(String[] args) {

        // -------- String iteration --------
        System.out.println("--- String iteration (chars) ---");
        String s = "Ashwani";
        for (char ch : s.toCharArray()) {
            System.out.print(ch + " ");
        }
        System.out.println("\n");

        // -------- Array iteration --------
        System.out.println("--- Array iteration ---");
        int[] arr = {10, 20, 30, 40};
        for (int x : arr) {
            System.out.print(x + " ");
        }
        System.out.println("\n");

        System.out.println("--- Array with index ---");
        for (int i = 0; i < arr.length; i++) {
            System.out.println("index=" + i + " value=" + arr[i]);
        }
        System.out.println();

        // -------- List (like Vec/LinkedList) --------
        System.out.println("--- List iteration ---");
        List<Integer> list = new ArrayList<>(Arrays.asList(1,2,3,4,5));
        for (int x : list) {
            System.out.print(x + " ");
        }
        System.out.println();

        System.out.println("--- Modify List (like iter_mut) ---");
        for (int i = 0; i < list.size(); i++) {
            list.set(i, list.get(i) * 10);
        }
        System.out.println("after modify => " + list);
        System.out.println();

        System.out.println("--- LinkedList iteration ---");
        LinkedList<Integer> linked = new LinkedList<>();
        linked.add(100); linked.add(200); linked.add(300);
        for (int x : linked) {
            System.out.print(x + " ");
        }
        System.out.println("\n");

        // -------- Map (dict) --------
        System.out.println("--- Map iteration ---");
        Map<String, Integer> map = new HashMap<>();
        map.put("apple", 3);
        map.put("banana", 5);

        for (Map.Entry<String, Integer> e : map.entrySet()) {
            System.out.println(e.getKey() + " => " + e.getValue());
        }
        System.out.println();

        System.out.println("--- Map keys ---");
        for (String key : map.keySet()) {
            System.out.print(key + " ");
        }
        System.out.println();

        System.out.println("--- Map values ---");
        for (int val : map.values()) {
            System.out.print(val + " ");
        }
        System.out.println("\n");

        // -------- Tuple --------
        System.out.println("--- Tuple3 (custom) ---");
        Tuple3<Integer, String, Boolean> t = new Tuple3<>(10, "hello", true);
        System.out.println("a=" + t.a + ", b=" + t.b + ", c=" + t.c);

        // -------- Stream pipeline (like Rust iterator chain) --------
        System.out.println("\n--- Pipeline on List (Stream) ---");
        List<Integer> nums = Arrays.asList(1,2,3,4,5,6);
        List<Integer> result = nums.stream()
                .filter(x -> x % 2 == 0)
                .map(x -> x * 100)
                .toList();

        System.out.println("even * 100 => " + result);
    }
}
Enter fullscreen mode Exit fullscreen mode

Output (Java)

--- String iteration (chars) ---
A s h w a n i 

--- Array iteration ---
10 20 30 40 

--- Array with index ---
index=0 value=10
index=1 value=20
index=2 value=30
index=3 value=40

--- List iteration ---
1 2 3 4 5 
--- Modify List (like iter_mut) ---
after modify => [10, 20, 30, 40, 50]

--- LinkedList iteration ---
100 200 300 

--- Map iteration ---
apple => 3
banana => 5

--- Map keys ---
apple banana 
--- Map values ---
3 5 

--- Tuple3 (custom) ---
a=10, b=hello, c=true

--- Pipeline on List (Stream) ---
even * 100 => [200, 400, 600]
Enter fullscreen mode Exit fullscreen mode

Array T; N

fn main() {
    let a = [10, 20, 30, 40];
    let sum: i32 = a.iter().sum();
    println!("{sum}");
}
Enter fullscreen mode Exit fullscreen mode

Output

100

2) String words iterator (split_whitespace)

fn main() {
    let s = "hi rust world";
    for w in s.split_whitespace() {
        println!("{w}");
    }
}

Enter fullscreen mode Exit fullscreen mode

Output

hi
rust
world

3) String chars iterator (chars)

fn main() {
    let s = "ABC";
    for c in s.chars() {
        print!("{c}-");
    }
    println!();
}
Enter fullscreen mode Exit fullscreen mode

Output

A-B-C-

4) String bytes iterator (bytes)

fn main() {
    let s = "AZ";
    for b in s.bytes() {
        println!("{b}");
    }
}
Enter fullscreen mode Exit fullscreen mode

Output


65
90
Enter fullscreen mode Exit fullscreen mode

5) Range iterator 1..=5

fn main() {
    let prod: i32 = (1..=5).product();
    println!("{prod}");
}
Enter fullscreen mode Exit fullscreen mode

Output

120

6) Infinite iterator + take

fn main() {
    let out: Vec<i32> = (0..).take(5).collect();
    println!("{:?}", out);
}
Enter fullscreen mode Exit fullscreen mode

Output

[0, 1, 2, 3, 4]
Enter fullscreen mode Exit fullscreen mode

7) Option as iterator (0 or 1 item)

fn main() {
    let x = Some(42);
    for v in x.into_iter() {
        println!("{v}");
    }
}
Enter fullscreen mode Exit fullscreen mode

Output

42

8) Result as iterator (Ok = 1 item, Err = 0)

fn main() {
    let r: Result<i32, &str> = Ok(7);
    let sum: i32 = r.into_iter().sum();
    println!("{sum}");
}
Enter fullscreen mode Exit fullscreen mode

Output

7

9) HashMap iteration (key/value)

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert("a", 10);
    m.insert("b", 20);

    let total: i32 = m.values().copied().sum();
    println!("{total}");
}
Enter fullscreen mode Exit fullscreen mode

Output

30

10) HashSet (unique values)

use std::collections::HashSet;

fn main() {
    let mut s = HashSet::new();
    s.insert(10);
    s.insert(10);
    s.insert(20);

    let cnt = s.iter().count();
    println!("{cnt}");
}
Enter fullscreen mode Exit fullscreen mode

Output

2

11) BTreeMap (sorted keys)

use std::collections::BTreeMap;

fn main() {
    let mut m = BTreeMap::new();
    m.insert(3, "c");
    m.insert(1, "a");
    m.insert(2, "b");

    for (k, v) in m.iter() {
        println!("{k}:{v}");
    }
}
Enter fullscreen mode Exit fullscreen mode

Output

1:a
2:b
3:c

12) VecDeque (queue) iteration

use std::collections::VecDeque;

fn main() {
    let mut q = VecDeque::new();
    q.push_back(1);
    q.push_back(2);
    q.push_front(0);

    for x in q.iter() {
        print!("{x} ");
    }
    println!();
}
Enter fullscreen mode Exit fullscreen mode

Output

0 1 2

13) LinkedList iteration

use std::collections::LinkedList;

fn main() {
    let mut l = LinkedList::new();
    l.push_back(10);
    l.push_back(20);

    let sum: i32 = l.iter().sum();
    println!("{sum}");
}
Enter fullscreen mode Exit fullscreen mode

Output

30

14) BinaryHeap iteration (order not sorted)

use std::collections::BinaryHeap;

fn main() {
    let mut h = BinaryHeap::new();
    h.push(1);
    h.push(5);
    h.push(3);

    println!("{}", h.peek().unwrap());
}

Enter fullscreen mode Exit fullscreen mode

Output

5

15) Slice iterator &T

fn main() {
    let a = [4, 8, 12];
    let slice: &[i32] = &a;
    let mx = slice.iter().max().unwrap();
    println!("{mx}");
}
Enter fullscreen mode Exit fullscreen mode

Output

12

16) lines() iterator from string (multi-line text)

fn main() {
    let text = "a\nb\nc\n";
    for line in text.lines() {
        println!("{line}");
    }
}
Enter fullscreen mode Exit fullscreen mode

Output

a
b
c

17) Iterator from stdin-like string (simulate reading)

fn main() {
    let input = "10\n20\nx\n30\n";
    let sum: i32 = input
        .lines()
        .filter_map(|s| s.parse::<i32>().ok())
        .sum();
    println!("{sum}");
}
Enter fullscreen mode Exit fullscreen mode

Output

60

18) repeat() infinite source

use std::iter;

fn main() {
    let out: String = iter::repeat("Hi")
        .take(3)
        .collect::<Vec<_>>()
        .join("-");
    println!("{out}");
}
Enter fullscreen mode Exit fullscreen mode

Output

Hi-Hi-Hi

19)successors() (generate sequence)

fn main() {
    let out: Vec<i32> = std::iter::successors(Some(1), |x| Some(x * 2))
        .take(5)
        .collect();
    println!("{:?}", out);
}

Enter fullscreen mode Exit fullscreen mode

Output

[1, 2, 4, 8, 16]

20) std::env::args() iterator (command-line args)

fn main() {
    let count = std::env::args().count();
    println!("{count}");
}
Enter fullscreen mode Exit fullscreen mode

Example Output (if you run app one two)

3

Summary

Why iterators are needed
iterators types--iter(),iter_mut(),into_iter(),Range iterators: 1..5, 1..=5,Iterator adapters (lazy transformations), Consumer (terminal) operations
iterator in key value pair using hashmap
Basic iter() + print
iter_mut() modify in place
into_iter() takes ownership
map
filter(),filter_map() (parse only valid numbers)
enumerate
take
skip
take_while(),skip_while(),
any() / all()
find
position
fold() (sum)
reduce() (max)
zip() (pair elements)
chain() (join two iterators)
flat_map() (flatten nested lists)
collect() into HashMap
String words iterator (split_whitespace)
String chars iterator (chars)
String bytes iterator (bytes)
Range iterator 1..=5
Infinite iterator + take
Result as iterator (Ok = 1 item, Err = 0)
HashMap iteration (key/value)
HashSet (unique values)
BTreeMap (sorted keys)
VecDeque (queue) iteration
lines() iterator from string (multi-line text)
Iterator from stdin-like string (simulate reading)
repeat() infinite source
Slice iterator &T
successors() (generate sequence)
std::env::args() iterator (command-line args)

Top comments (0)