> For the complete documentation index, see [llms.txt](https://bagus-cahyono.gitbook.io/programming-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bagus-cahyono.gitbook.io/programming-notes/rust/rustlings_exercise/05_vectors.md).

# Vectors

* A vector is a similar collection type provided by the standard library that is allowed to grow or shrink in size.
* Vectors are implemented using generics.
* More often, you’ll create a `Vec<T>` with initial values and Rust will infer the type of value you want to store, so you rarely need to do type annotation.
* References:
  * [Storing Lists of Values with Vectors](https://doc.rust-lang.org/book/ch08-01-vectors.html)
  * [Control Flow](https://doc.rust-lang.org/book/ch03-05-control-flow.html)
  * [Iterator](https://doc.rust-lang.org/std/iter/)
  * [Closure](https://doc.rust-lang.org/book/ch13-01-closures.html)

## vecs1.rs

```rust
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
    let a = [10, 20, 30, 40]; // Array

    // Create a vector called `v` which contains the exact same elements as in the array `a`.
    // Use the vector macro.
    // let v = ???;
    let v = vec![10, 20, 30, 40];
    (a, v)
}

fn main() {
    // You can optionally experiment here.
}

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

    #[test]
    fn test_array_and_vec_similarity() {
        let (a, v) = array_and_vec();
        assert_eq!(a, *v);
    }
}
```

* Rust conveniently provides the `vec!` macro, which will create a new vector that holds the values you give it.
* You can specify the vector types the type within angle brackets like `Vec<i32>`.
* More often, you’ll create a vector with initial values and Rust will infer the type of value you want to store, so you rarely need to do this type annotation.
* In this exercise we just need to init new vector using `vec!` macro.

  ```rust
  let v = vec![10, 20, 30, 40];
  ```

## vecs2.rs

```rust
fn vec_loop(input: &[i32]) -> Vec<i32> {
    let mut output = Vec::new();

    for element in input {
        // Multiply each element in the `input` slice by 2 and push it to
        // the `output` vector.
        output.push(element * 2);
    }

    output
}

fn vec_map_example(input: &[i32]) -> Vec<i32> {
    // An example of collecting a vector after mapping.
    // We map each element of the `input` slice to its value plus 1.
    // If the input is `[1, 2, 3]`, the output is `[2, 3, 4]`.
    input.iter().map(|element| element + 1).collect()
}

fn vec_map(input: &[i32]) -> Vec<i32> {
    // Here, we also want to multiply each element in the `input` slice
    // by 2, but with iterator mapping instead of manually pushing into an empty
    // vector.
    // See the example in the function `vec_map_example` above.
    input.iter().map(|element| element * 2).collect()
}

fn main() {
    // You can optionally experiment here.
}

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

    #[test]
    fn test_vec_loop() {
        let input = [2, 4, 6, 8, 10];
        let ans = vec_loop(&input);
        assert_eq!(ans, [4, 8, 12, 16, 20]);
    }

    #[test]
    fn test_vec_map_example() {
        let input = [1, 2, 3];
        let ans = vec_map_example(&input);
        assert_eq!(ans, [2, 3, 4]);
    }

    #[test]
    fn test_vec_map() {
        let input = [2, 4, 6, 8, 10];
        let ans = vec_map(&input);
        assert_eq!(ans, [4, 8, 12, 16, 20]);
    }
}
```

* In this exercise we have 2 task:
* First is to iterate through a collection manually using `for` and multiply each element with `2`.

  ```rust
  for element in input {
    output.push(element * 2);
  }
  ```

  * Multiple `element` by `2`.
  * Then push it into `output` variable.
  * You can read more about it in [Looping Through a Collection with for](https://doc.rust-lang.org/book/ch03-05-control-flow.html#looping-through-a-collection-with-for).
* Second is to iterate through a collection using iterators and multiply each element with `2`.

  ```rust
  input.iter().map(|element| element * 2).collect()
  ```

  * Calling `iter()` to a collection will return `Iter` type.
  * Then calling `map()` to produces a new iterator which calls given closure on each element of the original iterator. Ref: [trait.iterator method.map](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map).
  * `collect()` can take anything iterable, and turn it into a relevant collection.
  * You can read more about iterators in here: [Iteration](https://doc.rust-lang.org/std/iter/) and the trait here" [Iterator Trait](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
