有没有办法将两个迭代器合并到同一个Vec中?

问题描述 投票:1回答:2

我有两个迭代器将最终合并到相同的Vec,但我需要在合并之前对最终结果执行过滤。例如:

let a = vec![1, 2, 3, 4].into_iter().map(|x| x * 2);
let b = vec![0, 3, 5, 6, 7].into_iter().map(|x| x * 3);
let c = a + b;
assert_eq!(
    c.filter(|&x| x > 5).collect::<Vec<u8>>(),
    vec![6, 8, 9, 15, 18, 21]
);

我可以这样做:

let mut a = vec![1, 2, 3, 4]
    .into_iter()
    .map(|x| x * 2)
    .collect::<Vec<u8>>();
let b = vec![0, 3, 5, 6, 7]
    .into_iter()
    .map(|x| x * 3)
    .collect::<Vec<u8>>();
a.extend(b);
assert_eq!(
    a.into_iter().filter(|&x| x > 5).collect::<Vec<u8>>(),
    vec![6, 8, 9, 15, 18, 21]
);

但额外的分配会在我的情况下杀死性能(是的,我检查了!)

rust iterator
2个回答
8
投票

你在找Iterator::chain

let a = vec![1, 2, 3, 4].into_iter().map(|x| x * 2);
let b = vec![0, 3, 5, 6, 7].into_iter().map(|x| x * 3);
let c = a.chain(b);
assert_eq!(
    c.filter(|&x| x > 5).collect::<Vec<u8>>(),
    vec![6, 8, 9, 15, 18, 21]
);

1
投票

或者,您可以使用extend()

let a = (0..500000).map(|x| x * 2);
let b = (0..500000).map(|x| x * 3);
let mut c = Vec::with_capacity(a.size_hint().1.unwrap() + b.size_hint().1.unwrap());
c.extend(a);
c.extend(b);

这要求你明确使用with_capacity()chain()为你做的collect()。在a已经建成的情况下,extend()将适合而不是构建临时向量。

在这种情况下,我没有找到chain()extend之间的任何基准差异(benchmark

这不会进行过滤。 Sebastian Redl

正确!修复此错误表明,由于某种原因,LLVM现在不再优化chain()。与extend的版本:

let a = (0..500000).map(|x| x * 2);
let b = (0..500000).map(|x| x * 3);
let mut c = Vec::with_capacity(a.size_hint().1.unwrap() + b.size_hint().1.unwrap());
c.extend(a.filter(|&x| x > 5));
c.extend(b.filter(|&x| x > 5));

比使用chain的版本快两倍(这是我首先想到的):

let a = (0..500000).map(|x| x * 2);
let b = (0..500000).map(|x| x * 3);
let _c: Vec<_> = a.chain(b).filter(|&x| x > 5).collect();

(Qazxswpoi)

© www.soinside.com 2019 - 2024. All rights reserved.