gpt4 book ai didi

functional-programming - 迭代连续折叠结果的惯用和功能方法是什么?

转载 作者:行者123 更新时间:2023-11-29 08:27:08 25 4
gpt4 key购买 nike

我有一个序列(列表,迭代器)a0, a1, a2, ...,我使用一个函数f来折叠。我想要一个能给我

a0, f(a0, a1), f(f(a0, a1), a2), ...

这类似于 Mathematica 中的 FoldList。是否有可用的 fold_list 功能?我找不到。

最佳答案

我会说最接近的抽象是 Iterator::scan .它有点更强大,因为它有一个内部可变状态(即可以为结果迭代器产生不同的值)并且可以提前中止。

您可以像这样使用它来构建迭代器扩展特征:

Playground

pub trait FoldListExt: Iterator {
fn fold_list<'a, St: 'a, F: 'a>(self, initial_state: St, f: F) -> Box<Iterator<Item = St> + 'a>
where
St: Clone,
F: FnMut(St, Self::Item) -> St,
Self: 'a;
}

impl<I: Iterator> FoldListExt for I {
fn fold_list<'a, St: 'a, F: 'a>(
self,
initial_state: St,
mut f: F,
) -> Box<Iterator<Item = St> + 'a>
where
St: Clone,
F: FnMut(St, Self::Item) -> St,
Self: 'a,
{
Box::new(self.scan(Some(initial_state), move |state, item| {
let old_state = state.take().unwrap();
*state = Some(f(old_state.clone(), item));
Some(old_state)
}))
}
}

pub fn main() {
println!(
"{:?}",
(0..16)
.into_iter()
.fold_list(0, |a, b| a + b)
.collect::<Vec<_>>()
);
}

我用了Option<St>为内部可变状态避免另一个 clone()打电话。

您可以改用它:

Box::new(self.scan(initial_state, move |state, item| {
let old_state = state.clone();
*state = f(old_state.clone(), item);
Some(old_state)
}))

关于functional-programming - 迭代连续折叠结果的惯用和功能方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47960371/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com