Метод scan
Метод scan создаёт новый итератор, который
применяет указанную функцию к каждому элементу
исходного итератора, сохраняя промежуточное
состояние между вызовами. Метод принимает два
параметра: начальное значение состояния и функцию,
которая получает изменяемую ссылку на состояние
и текущий элемент, а возвращает Option.
Если функция возвращает Some, значение
попадает в новый итератор, если None -
итерация завершается.
Синтаксис
iter.scan(init, f)
Пример
Давайте создадим итератор, который накапливает сумму элементов вектора:
fn main()
{
let vec = vec![1, 2, 3, 4, 5];
let res: Vec<i32> = vec.iter()
.scan(0, |acc, x| {
*acc += x;
Some(*acc)
})
.collect();
println!("{:?}", res);
}
Результат выполнения кода:
[1, 3, 6, 10, 15]
Пример
Давайте создадим итератор, который прекращает работу, когда накопленная сумма превысит заданное значение:
fn main()
{
let vec = vec![1, 2, 3, 4, 5];
let res: Vec<i32> = vec.iter()
.scan(0, |acc, x| {
*acc += x;
if *acc > 6 {
None
} else {
Some(*acc)
}
})
.collect();
println!("{:?}", res);
}
Результат выполнения кода:
[1, 3, 6]
Пример
Давайте используем scan для накопления
строки из символов:
fn main()
{
let vec = vec!["a", "b", "c", "d", "e"];
let res: Vec<String> = vec.iter()
.scan(String::new(), |acc, x| {
acc.push_str(x);
Some(acc.clone())
})
.collect();
println!("{:?}", res);
}
Результат выполнения кода:
["a", "ab", "abc", "abcd", "abcde"]
Смотрите также
-
метод
fold,
который сворачивает итератор в одно значение -
метод
map,
который преобразует каждый элемент итератора -
метод
filter_map,
который одновременно фильтрует и преобразует элементы -
метод
collect,
который собирает элементы итератора в коллекцию