Как я могу уменьшить (сложить) итератор и сохранить промежуточные результаты (такие как накопленная сумма)? - PullRequest
2 голосов
/ 11 марта 2019

Я хочу применить сокращение к итератору, но мне не нужно только конечное значение, промежуточные результаты тоже важны.

В качестве примера давайте преобразуем вектор расстояний в вектор позиций:

let distances = vec![3, 2, 1, 4];
// create positions vector [3, 5, 6, 10]

Моя попытка решения использует map и замыкание:

let mut acc = 0;
let positions: Vec<i32> = distances
    .iter()
    .map(|x| {
        acc = acc + x;
        acc
    })
    .collect();

Хороший комментарий от @starblue: Для суммирования лучше всего подойдет fold.Он применяет сокращение и возвращает последнее значение.Это не возвращает промежуточные решения, хотя:

// basically exact code from fold example in the docs
let last_position = distances.iter().fold(0, |acc, x| acc + x);

1 Ответ

5 голосов
/ 11 марта 2019

Я вижу, что должен был прочитать документы более внимательно.Функция, которую я ищу, называется scan.Вот кумулятивная сумма реализации:

let distances = vec![3, 2, 1, 4];
let positions: Vec<i32> = distances
        .iter()
        .scan(0, |acc, &x| {
            *acc = *acc + x;
            Some(*acc)
        })
        .collect();
...