gpt4 book ai didi

iterator - 如何在不收集临时向量的情况下对结果的迭代器执行迭代器计算?

转载 作者:行者123 更新时间:2023-12-03 11:40:01 24 4
gpt4 key购买 nike

在此示例中,我正在寻找一种消除临时向量分配的方法:

fn doit<T: Iterator<Item = Result<i32, &'static str>>>(name: &str, iter: T) {
println!(
"{}: {:?}",
name,
iter.collect::<Result<Vec<_>, _>>()
.map(|v| v.into_iter().min())
);
}

fn main() {
let without_errors = vec![Ok(1), Ok(2), Ok(3)];
let with_errors = vec![Ok(1), Err("error"), Ok(2)];

doit("without errors", without_errors.into_iter());
doit("with errors", with_errors.into_iter());
}

这是具有错误处理主题的迭代器的一种变体,只是我不想创建一个集合(因此 collect()不能完全完成工作),但是我想对要迭代的元素执行进一步的操作。

请注意,这会产生错误的结果,因为 Ok小于 Err:
fn doit<T: Iterator<Item = Result<i32, &'static str>>>(name: &str, iter: T) {
println!("{}: {:?}", name, iter.min());
}

偶然会为 max()提供正确的结果,但不会停止对第一个错误的迭代。

最佳答案

Iterator::try_fold 提供了您所需的框架,并且从Rust 1.27(Playground)开始就可以使用:

fn fold_ok<I, T, E, F>(mut iter: I, f: F) -> Result<Option<T>, E>
where
I: Iterator<Item = Result<T, E>>,
T: Ord,
F: Fn(T, T) -> T,
{
iter.try_fold(None, |r, i| {
let i = i?;
Ok(Some(if let Some(r) = r { f(r, i) } else { i }))
})
}

fn main() {
let without_errors = vec![Ok(1), Ok(2), Ok(3)];
let with_errors = vec![Ok(1), Err("error"), Ok(2)];

fn doit<'r, T>(name: &str, iter: T)
where
T: Iterator<Item = &'r Result<i32, &'static str>> + Clone,
{
println!("{}: {:?}", name, fold_ok(iter.cloned(), ::std::cmp::min));
}

doit("without errors", without_errors.iter());
doit("with errors", with_errors.iter());
}

在此之前,我认为您唯一的选择是手动迭代( Playground)
fn fold_ok<I, T, E, F>(mut iter: I, f: F) -> Result<Option<T>, E>
where
I: Iterator<Item = Result<T, E>>,
T: Ord,
F: Fn(T, T) -> T,
{
let mut result = match iter.next() {
None => return Ok(None),
Some(r) => r?,
};

for item in iter {
result = f(result, item?);
}

Ok(Some(result))
}

fn main() {
let without_errors = vec![Ok(1), Ok(2), Ok(3)];
let with_errors = vec![Ok(1), Err("error"), Ok(2)];

fn doit<'r, T>(name: &str, iter: T)
where
T: Iterator<Item = &'r Result<i32, &'static str>> + Clone,
{
println!(
"{}: {:?}",
name,
fold_ok(iter.clone().cloned(), ::std::cmp::min)
);
}

doit("without errors", without_errors.iter());
doit("with errors", with_errors.iter());
}

关于iterator - 如何在不收集临时向量的情况下对结果的迭代器执行迭代器计算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57679497/

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