๐Ÿฆ€ Functional Rust
๐ŸŽฌ How Rust Iterators Work Lazy evaluation, chaining, collect(), and zero-cost abstractions.
๐Ÿ“ Text version (for readers / accessibility)

โ€ข Iterators are lazy โ€” .map(), .filter(), .take() build a chain but do no work until consumed

โ€ข .collect() triggers evaluation, transforming the chain into a Vec, HashMap, or other collection

โ€ข Zero-cost abstraction: iterator chains compile to the same machine code as hand-written loops

โ€ข .iter() borrows, .into_iter() consumes, .iter_mut() borrows mutably

โ€ข Chaining replaces nested loops with a readable, composable pipeline

277: Iterator count()

Difficulty: 1 Level: Beginner Consume an iterator and return the total number of elements as `usize`.

The Problem This Solves

You need to know how many elements satisfy a condition โ€” how many words in a text, how many even numbers in a range, how many log lines match an error pattern. Without `count()`, you'd write a fold accumulating an integer counter, or collect into a Vec and call `.len()` โ€” wasteful if you only want the count. `count()` composes naturally with `filter()`: `iter.filter(pred).count()` is the idiomatic "count matching elements" pattern. It's one expression, one traversal, no intermediate allocation. For ranges and slices (which implement `ExactSizeIterator`), `count()` runs in O(1) โ€” it just reads the stored length. The catch: `count()` consumes the iterator. You can't use it again afterward. For slices, if you only want the length, prefer `.len()` directly โ€” it's O(1) and doesn't move anything.

The Intuition

Walk the entire iterator and tally the elements, returning the total as `usize`.

How It Works in Rust

let nums: Vec<i32> = (1..=10).collect();

// Basic count
nums.iter().count();  // 10

// Count matching elements โ€” one expression, no intermediate Vec
nums.iter().filter(|&&x| x % 2 == 0).count();  // 5

// Count characters matching a predicate
"hello world".chars().filter(|c| "aeiou".contains(*c)).count();  // 3

// Count words
"the quick brown fox".split_whitespace().count();  // 4

// Range count is O(1) โ€” ExactSizeIterator knows its length
(0usize..1_000_000).count();  // 1_000_000, instant

// Combine with take_while for "how many elements before X"
let sorted = [1, 3, 5, 7, 9, 11];
sorted.iter().take_while(|&&x| x < 10).count();  // 5
`count()` returns `usize` โ€” unsigned, platform-sized. Can't be negative, can't be used in signed arithmetic without casting.

What This Unlocks

Key Differences

ConceptOCamlRust
Count list`List.length lst``iter.count()`
Count matching`List.length (List.filter p lst)``iter.filter(p).count()`
ComplexityO(n) alwaysO(n); O(1) for `ExactSizeIterator`
Return type`int` (signed)`usize` (unsigned, platform-sized)
After countingList still availableIterator consumed โ€” can't reuse
//! 277. Counting with count()
//!
//! `count()` consumes an iterator and returns the total number of elements.

fn main() {
    let nums: Vec<i32> = (1..=10).collect();
    println!("Count: {}", nums.iter().count());

    let even_count = nums.iter().filter(|&&x| x % 2 == 0).count();
    println!("Even count: {}", even_count);

    let s = "hello world";
    let vowels = s.chars().filter(|c| "aeiou".contains(*c)).count();
    println!("Vowels in '{}': {}", s, vowels);

    let text = "the quick brown fox jumps over the lazy dog";
    println!("Word count: {}", text.split_whitespace().count());

    // Efficient count for Range (ExactSizeIterator โ€” O(1))
    let range_count = (0usize..1_000_000).count();
    println!("Range count: {}", range_count);

    let sorted = [1i32, 3, 5, 7, 9, 11, 13];
    let under_10 = sorted.iter().take_while(|&&x| x < 10).count();
    println!("Elements < 10: {}", under_10);
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_count_basic() {
        assert_eq!((1..=10).count(), 10);
    }

    #[test]
    fn test_count_filter() {
        let evens = (1..=10).filter(|x| x % 2 == 0).count();
        assert_eq!(evens, 5);
    }

    #[test]
    fn test_count_empty() {
        let empty: Vec<i32> = vec![];
        assert_eq!(empty.iter().count(), 0);
    }

    #[test]
    fn test_count_string_chars() {
        let vowels = "hello".chars().filter(|c| "aeiou".contains(*c)).count();
        assert_eq!(vowels, 2);
    }
}
(* 277. Counting with count() - OCaml *)

let () =
  let nums = List.init 10 (fun i -> i + 1) in
  Printf.printf "Count: %d\n" (List.length nums);

  let evens = List.length (List.filter (fun x -> x mod 2 = 0) nums) in
  Printf.printf "Evens: %d\n" evens;

  let s = "hello world" in
  let vowels = String.fold_left
    (fun acc c -> if String.contains "aeiou" c then acc + 1 else acc) 0 s in
  Printf.printf "Vowels in '%s': %d\n" s vowels;

  let text = "the quick brown fox jumps over the lazy dog" in
  Printf.printf "Word count: %d\n"
    (List.length (String.split_on_char ' ' text))