首页 > 解决方案 > 检索 scan() 迭代器中的状态?

问题描述

要获得整数序列的部分和,我可以scan()像这样在迭代器上使用:

let partial: Box<[u32]> =
    list
    .iter()
    .scan(0, |st, elem| {
        let ret = *st;
        *st += elem;
        Some(ret)
    })
    .collect();

上面的代码运行良好,但我正在尝试修改它以给我总和。

就像是:

let (partial, total): (Box<[u32]>, u32) =
    list
    .iter()
    .scan(0, |st, elem| {
        // TODO
    })
    .collect();

似乎我只需要获取 的最终值st,并且迭代器应该已经知道它的值。但是,我似乎无法找到一种方法来检索该值,除非对整个序列进行第二次迭代(例如 with fold())。

有没有办法一次性找到部分总和和总和?

标签: rustiterator

解决方案


将总和包括在 中scan,然后拆分出最后一个值。

use std::iter;

fn main() {
    let list = vec![1, 2, 3, 4];

    // Add zero at the start to emulate what you had before
    let partial: Box<[u32]> = iter::once(0)
        .chain(list.iter().scan(0, |st, elem| {
            *st += elem;
            Some(*st)
        }))
        .collect();
    // unwrap since with the added zero, the slice will always be non-empty
    let (total, partial) = partial.split_last().unwrap();

    println!("partial sums: {:?}", partial);
    println!("total sum: {}", total);
}

(操场)


或使用successors()

fn main() {
    use std::iter::successors;

    let list = vec![1, 2, 3, 4];

    let mut iter = list.iter();
    let partial: Vec<_> = successors(Some(0), |n| iter.next().map(|i| n + i)).collect();
    // unwrap since with the added zero, the slice will always be non-empty
    let (total, partial) = partial.split_last().unwrap();

    assert_eq!(partial, &[0, 1, 3, 6]);
    assert_eq!(total, &10);
}

(操场)


推荐阅读