# Iterators

The iterator pattern allows you to perform some task on a sequence of items in turn. Iterators provide a way to traverse, transform, or consume elements efficiently without needing to manually manage indices or loops.

Rust iterators are lazy by default, meaning they don’t perform operations until explicitly consumed.

> **Closures** and **iterators** are Rust features inspired by functional programming language ideas. They contribute to Rust’s capability to clearly express high-level ideas at low-level performance. The implementations of closures and iterators are such that runtime performance is not affected. This is part of Rust’s goal to strive to provide zero-cost abstractions. - [Comparing Performance: Loops vs. Iterators](https://doc.rust-lang.org/book/ch13-04-performance.html)

## Iterator Trait

An iterator is any type that implements the Iterator trait. The Iterator trait has one required method:

```rust
fn next(&mut self) -> Option<Self::Item>;
```

`next` returns the next item in the sequence wrapped in `Some` or `None` if the iterator is exhausted.

> Advances the iterator and returns the next value.
>
> Returns `None` when iteration is finished. Individual iterator implementations may choose to resume iteration, and so calling `next()` again may or may not eventually start returning `Some(Item`) again at some point.

**Example**:

```rust
fn main() {
    let numbers = vec![1, 2, 3];
    let mut iter = numbers.iter();

    println!("{:?}", iter.next());
    println!("{:?}", iter.next());
    println!("{:?}", iter.next());
    println!("{:?}", iter.next());
}
```

**Output**:

```bash
Some(1)
Some(2)
Some(3)
None
```

## Consumer Adapters

The Iterator trait has a number of different methods with default implementations provided by the standard library. Methods that call next are called ***consuming adapters***, because calling them uses up the iterator.

Some of commonly used consumer adapters methods: `count`, `sum`, `fold`, `product`, `collect`, etc. You can find more of the provided method here: <https://doc.rust-lang.org/std/iter/trait.Iterator.html#provided-methods>.

### Examples

#### Sum

```rust
fn sum<S>(self) -> S
where
    Self: Sized,
    S: Sum<Self::Item>,
```

* Sums the elements of an iterator.
* Takes each element, adds them together, and returns the result.
* An empty iterator returns the zero value of the type.
* Example:

  ```rust
  fn main() {
      let numbers = vec![1, 2, 3];
      let iter = numbers.iter();
      let x: i32 = iter.sum();

      println!("{:?}", x); // 6
  }
  ```

#### Fold

```rust
fn fold<B, F>(self, init: B, f: F) -> B
where
    Self: Sized,
    F: FnMut(B, Self::Item) -> B,
```

* Folds every element into an accumulator by applying an operation, returning the final result.
* `fold()` takes two arguments: an initial value, and a closure with two arguments: an ‘accumulator’, and an element. The closure returns the value that the accumulator should have for the next iteration.
* The initial value is the value the accumulator will have on the first call.
* After applying this closure to every element of the iterator, `fold()` returns the accumulator.
* Example:

  ```rust
  fn main() {
      let numbers = vec![1, 2, 3];
      let iter = numbers.iter();
      let x: i32 = iter.fold(0, |acc, &x| acc + x * x);

      println!("{:?}", x); // 14
  }
  ```

## Iterator Adapters

**Iterator adapters** are methods defined on the Iterator trait that don’t consume the iterator. Instead, they produce different iterators by changing some aspect of the original iterator.

Some of commonly used iterator adapters method: `map`, `filter`, `take`, `skip`, `enumerate`, etc. Again, you can find more of the provided method here: <https://doc.rust-lang.org/std/iter/trait.Iterator.html#provided-methods>.

### Examples

#### Map

```rust
fn map<B, F>(self, f: F) -> Map<Self, F> ⓘ
where
    Self: Sized,
    F: FnMut(Self::Item) -> B,
```

* Takes a closure and creates an iterator which calls that closure on each element.
* `map()` transforms one iterator into another, by means of its argument: something that implements `FnMut`. It produces a new iterator which calls this closure on each element of the original iterator.
* If you are good at thinking in types, you can think of `map()` like this: If you have an iterator that gives you elements of some type `A`, and you want an iterator of some other type `B`, you can use `map()`, passing a closure that takes an `A` and returns a `B`.

  ```rust
  fn main() {
      let numbers = vec![1, 2, 3];
      let doubled: Vec<i32> = numbers.iter().map(|x| x * 2).collect();

      println!("{:?}", doubled); // [2, 4, 6]
  }
  ```

#### Filter

```rust
fn filter<P>(self, predicate: P) -> Filter<Self, P> ⓘ
where
    Self: Sized,
    P: FnMut(&Self::Item) -> bool,
```

* Creates an iterator which uses a closure to determine if an element should be yielded.
* Given an element the closure must return `true` or `false`. The returned iterator will yield only the elements for which the closure returns `true`.
* Example:

  ```rust
  fn main() {
      let numbers = vec![1, 2, 3];
      // Filter number that != 2
      let mut iter = numbers.iter().filter(|x| **x != 2);

      println!("{:?}", iter.next()); // Some(1)
      println!("{:?}", iter.next()); // Some(3)
      println!("{:?}", iter.next()); // None
  }
  ```

## The Power of `collect()`

```rust
fn collect<B>(self) -> B
where
    B: FromIterator<Self::Item>,
    Self: Sized,
```

The `collect` method is part of the `Iterator` trait and is used to transform an iterator into a collection. It relies on the `FromIterator` trait to determine how to build the target type.

Example of `Vec::from_iter`:

```rust
fn main() {
    let five_fives = std::iter::repeat(5).take(5);
    let v = Vec::from_iter(five_fives);

    println!("{:?}", v); // [5, 5, 5, 5, 5]
}
```

`collect()` can take anything iterable, and turn it into a relevant collection. This is one of the more powerful methods in the standard library, used in a variety of contexts.

The most basic pattern in which `collect()` is used is to turn one collection into another. You take a collection, call `iter` on it, do a bunch of transformations, and then `collect()` at the end.

Example of `collect`:

```rust
fn main() {
    fn take_vec(v: Vec<i32>) {
        println!("{:?}", v) // [2, 4, 6]
    }
    
    let numbers = vec![1, 2, 3];
    let doubled = numbers.iter().map(|x| x * 2).collect();
    take_vec(doubled); // Compiler infers the target type as Vec<i32>
}
```

* So in here Rust will check for the target type when `collect` is called.
* As we can see the function `take_vec` is expecting a type `Vec<i32>`.
* Rust compiler then will infer the target of `collect` is `Vec<i32>`.
* And because `Vec` has `FromIterator` trait, it will call `Vec::from_iter` function and produce the result.

### Why `collect` Fails Sometimes?

There are various reason that sometimes `collect` cannot built the targeted type, some's are:

* **Ambiguous Target Type**: If the target type is not clear from the context.
* **Type Mismatch**: If the iterator produces items that cannot be converted to the target type.
* **Unsupported Target Type**: If the target type doesn’t implement FromIterator.

  Though, we can implement `FromIterator` if we have our own custom type like this:

  ```rust
  fn main() {
      use std::iter::FromIterator;

      #[derive(Debug)]
      struct MyType(Vec<i32>);
      
      impl FromIterator<i32> for MyType {
          fn from_iter<I: IntoIterator<Item = i32>>(iter: I) -> Self {
              MyType(iter.into_iter().collect())
          }
      }
      
      let numbers = vec![1, 2, 3];
      let result: MyType = numbers.into_iter().collect();
      println!("{:?}", result); // MyType([1, 2, 3])
  }
  ```

## `iter` vs `iter_mut` vs `into_iter`

### `.iter()`

* Returns an iterator of references (`&T`) over the elements of the collection.
* The collection is not consumed.
* Cannot modify the original collection’s elements (unless combined with `.iter_mut()`).

**Example**:

```rust
fn main() {
    let numbers = vec![1, 2, 3];
    let sum: i32 = numbers.iter().sum();
    println!("Sum: {:?}", sum); // Sum: 6 
    println!("Vec: {:?}", numbers); // Vec: [1, 2, 3]
}
```

### `.iter_mut()`

* Returns an iterator of mutable references (`&mut T`) over the elements of the collection.
* For modifying elements of a collection in place.

**Example**:

```rust
fn main() {
    let mut numbers = vec![1, 2, 3];
    println!("Vec: {:?}", numbers); // Vec: [1, 2, 3]
    numbers.iter_mut().for_each(|x| *x *= 2);
    println!("Vec: {:?}", numbers); // Vec: [2, 4, 6]
}
```

### `.into_iter()`

* Consumes the collection and returns an iterator of owned values (`T`).
* Moving ownership of each element.
* After calling `.into_iter()`, the original collection cannot be used anymore because ownership is transferred to the iterator.

**Exmaple**:

```rust
fn main() {
    let numbers = vec![1, 2, 3];
    let doubled: Vec<i32> = numbers.into_iter().map(|x| x * 2).collect();
    println!("Vec: {:?}", doubled); // Vec: [2, 4, 6]
    println!("Vec: {:?}", numbers); // error[E0382]: borrow of moved value: `numbers`
}
```

## References

* <https://doc.rust-lang.org/book/ch13-02-iterators.html>
* <https://doc.rust-lang.org/book/ch13-04-performance.html>
* <https://doc.rust-lang.org/std/iter/trait.Iterator.html>
* <https://doc.rust-lang.org/std/iter/trait.FromIterator.html>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bagus-cahyono.gitbook.io/programming-notes/rust/iterators.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
