๐Ÿฆ€ 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

099: Group By Iter

Difficulty: Intermediate Category: Iterators Concept: Group consecutive equal elements Key Insight: Grouping consecutive elements is useful for RLE encoding, data aggregation, and stream processing
// 099: Group Consecutive Equal Elements

fn group_by<T: PartialEq + Clone>(v: &[T]) -> Vec<Vec<T>> {
    if v.is_empty() { return vec![]; }
    let mut groups: Vec<Vec<T>> = vec![vec![v[0].clone()]];
    for item in &v[1..] {
        if item == groups.last().unwrap().last().unwrap() {
            groups.last_mut().unwrap().push(item.clone());
        } else {
            groups.push(vec![item.clone()]);
        }
    }
    groups
}

fn main() {
    println!("{:?}", group_by(&[1, 1, 2, 2, 2, 3, 1, 1]));
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_group_by() {
        assert_eq!(
            group_by(&[1, 1, 2, 2, 2, 3, 1, 1]),
            vec![vec![1, 1], vec![2, 2, 2], vec![3], vec![1, 1]]
        );
    }

    #[test]
    fn test_empty() {
        assert_eq!(group_by::<i32>(&[]), Vec::<Vec<i32>>::new());
    }

    #[test]
    fn test_single() {
        assert_eq!(group_by(&[1]), vec![vec![1]]);
    }

    #[test]
    fn test_all_same() {
        assert_eq!(group_by(&[5, 5, 5]), vec![vec![5, 5, 5]]);
    }
}
(* 099: Group Consecutive Equal Elements *)

let group_by lst =
  match lst with
  | [] -> []
  | x :: xs ->
    let rec aux current group acc = function
      | [] -> List.rev (List.rev (current :: group) :: acc)
      | h :: t ->
        if h = current then aux current (h :: group) acc t
        else aux h [h] (List.rev (current :: group) :: acc) t
    in
    aux x [] [] xs

(* Tests *)
let () =
  assert (group_by [1;1;2;2;2;3;1;1] = [[1;1];[2;2;2];[3];[1;1]]);
  assert (group_by [] = []);
  assert (group_by [1] = [[1]]);
  Printf.printf "โœ“ All tests passed\n"

๐Ÿ“Š Detailed Comparison

Core Insight

Grouping consecutive elements is useful for RLE encoding, data aggregation, and stream processing

OCaml Approach

  • See example.ml for implementation

Rust Approach

  • See example.rs for implementation

Comparison Table

FeatureOCamlRust
Seeexample.mlexample.rs