Iterators
Links:
- https://doc.rust-lang.org/book/ch13-02-iterators.html
- https://dev.to/martcpp/understanding-map-vs-flatmap-in-rust-with-a-simple-analogy-408g
Итераторы
Итераторы позволяют выполнять действия по очереди над цепочкой данных. Итератор берёт каждый объект цепочки и проверяет, не последний или он. Итераторы в Rust - ленивые, т.е не отрабатывают, пока не будет вызван метод, который их поглощает.
let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
for val in v1_iter { // iterator consume by for cycle
println!("Got: {val}");
}repeat, take, repeat_n
repeat - создаёт строку, повторяя заданный символ N раз (N as usize).
Например, вывести квадрат из символов “+” размера n (через клонирование):
fn generate_square(n: i32) -> String {
vec!["+".repeat(n as usize); n as usize].join("\n") }repeat_n - создаёт итератор, который возвращает заданный элемент N раз (N as usize) без клонирования (в отличие от repeat):
fn generate_square2(n: i32) -> String {
std::iter::repeat_n(
std::iter::repeat_n("+", n as usize).collect::<String>(),
n as usize,
)
.collect::<Vec<_>>()
.join("\n") }take - возвращает первые N элементов итератора (N as usize), если итератор не исчерпает себя раньше:
fn generate_square3(n: i32) -> String {
std::iter::repeat(std::iter::repeat("+").take(n as usize).collect::<String>()).take(n as usize).collect::<Vec<_>>().join("\n") }take часто используют с бесконечным итератором для задания ему конечного числа итераций:
let mut iter = (0..).take(3);
assert_eq!(iter.next(), Some(0));
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);Отличие .map() и .flat_map()
Обе функции раскрывают итератор вектора, однако, с разным результатом:
fn main() {
let numbers = vec![1, 2, 3];
// Using `map()`
let mapped: Vec<Vec<i32>> = numbers.iter().map(|&n| vec![n, n * 10]).collect();
println!("{:?}", mapped); // [[1, 10], [2, 20], [3, 30]]
// Using `flat_map()`
let flat_mapped: Vec<i32> = numbers.iter().flat_map(|&n| vec![n, n * 10]).collect();
println!("{:?}", flat_mapped); // [1, 10, 2, 20, 3, 30]
}.map() - сохраняет структуру в итоговом результате .flat_map() - убирает лишние структуры