Rust Guide > Documentation > Iterators > Enumerate

Introduction

The enumerate function in Rust is a method provided by the Iterator trait that adds a counter to the iteration, returning an iterator of pairs where the first element is the counter and the second is the item. This function is useful when you need both the index and the value of each element in a collection.

Syntax

The basic syntax of the enumerate function is as follows:

iterator.enumerate()

Here, iterator is any type that implements the Iterator trait. The resulting iterator yields tuples of the form (index, item).

Example Usage

Example 1: Enumerating Elements in a Vector

fn main() {
    let numbers = vec![10, 20, 30, 40];
    for (index, value) in numbers.iter().enumerate() {
        println!("Index: {}, Value: {}", index, value);
    }
    // Output:
    // Index: 0, Value: 10
    // Index: 1, Value: 20
    // Index: 2, Value: 30
    // Index: 3, Value: 40
}

Example 2: Enumerating Characters in a String

fn main() {
    let text = "Rust";
    for (index, ch) in text.chars().enumerate() {
        println!("Index: {}, Character: {}", index, ch);
    }
    // Output:
    // Index: 0, Character: R
    // Index: 1, Character: u
    // Index: 2, Character: s
    // Index: 3, Character: t
}

Example 3: Using Enumerate with Map

fn main() {
    let numbers = vec![1, 2, 3, 4];
    let indexed_squares: Vec<(usize, i32)> = numbers.iter()
                                                    .enumerate()
                                                    .map(|(index, &num)| (index, num * num))
                                                    .collect();
    println!("{:?}", indexed_squares);
    // Output: [(0, 1), (1, 4), (2, 9), (3, 16)]
}

Example 4: Enumerating Lines in a Text

fn main() {
    let text = "First linenSecond linenThird line";
    for (index, line) in text.lines().enumerate() {
        println!("Line {}: {}", index + 1, line);
    }
    // Output:
    // Line 1: First line
    // Line 2: Second line
    // Line 3: Third line
}

Example 5: Enumerating and Filtering

fn main() {
    let numbers = vec![5, 10, 15, 20, 25];
    let filtered: Vec<(usize, &i32)> = numbers.iter()
                                              .enumerate()
                                              .filter(|&(index, &num)| index % 2 == 0)
                                              .collect();
    println!("{:?}", filtered);
    // Output: [(0, 5), (2, 15), (4, 25)]
}

Considerations

  • The index provided by enumerate is zero-based; it starts from 0 and increments by 1 for each element.
  • Remember that the index and the element are returned as a tuple, so pattern matching is often used to destructure the tuple in for loops or closures.

See Also

  • filter - Creates an iterator that only yields elements that satisfy a predicate.
  • map - Transforms each element of an iterator and returns a new iterator with the transformed elements.
  • collect - Transforms an iterator into a collection such as a vector or hash map.
  • take - Creates an iterator that yields the first n elements.
  • for_each - Applies a closure to each element of an iterator for side effects.