类似这个问题:How do I interleave two Rust vectors by chunks of threes into a new vector?
相反,我想执行相反的行为。将迭代器分成两个不同的迭代器而不必收集它们的内容(又名我不想使用 unzip )。
此外,我想分离一个迭代器,而不收集原始迭代器的全部内容。
这是一个半示例:
#[derive(Debug)]
struct Foo(i32);
fn main() {
// note array elements of Foo cannot be copied or cloned
// v1: [0, 1, 2, 3]
// v2: [4, 5, 6, 7]
let v1 = (0..4).map(|num| Foo(num)).collect::<Vec<_>>();
let v2 = (4..8).map(|num| Foo(num)).collect::<Vec<_>>();
// generate interleaved iterator
// interleaved: [0, 1, 4, 5, 2, 3, 6, 7]
let interleaved = v1.chunks(2)
.zip(v2.chunks(2))
.flat_map(|(c1, c2)| c1.iter().chain(c2));
println!("interleaved: {:?}", interleaved.collect::<Vec<_>>());
// regenerate interleaved iterator
let interleaved = v1.chunks(2)
.zip(v2.chunks(2))
.flat_map(|(c1, c2)| c1.iter().chain(c2));
let mut v3: Vec<&Foo> = vec![];
let mut v4: Vec<&Foo> = vec![];
for (idx, item) in interleaved.enumerate() {
if idx % 4 < 2 {
v3.push(item);
} else {
v4.push(item);
}
}
println!("v3: {:?}, v4: {:?}", v3, v4);
}
我想找到一种惯用的解决方案来取消迭代器的交错,而不必将它们的引用收集到容器中。
更一般地说,我想弄清楚如何将 n
个元素的迭代器减少到 m
个元素,其中 n >= m
。在本例中,我希望将长度为 8 的交错迭代器减少为长度为 4 的 block 为 2 的迭代器。然后分块迭代器将被分成另外两个迭代器。
从这个意义上说,我想将我的迭代器“解析”为 2 个 block 。
最佳答案
如果原始迭代器实现了Clone
,那么您可以克隆它并分别执行enumerate()
+ filter()
:
fn uninterleave<T, I: Iterator<Item = T> + Clone>(
iter: I,
) -> (impl Iterator<Item = T>, impl Iterator<Item = T>) {
let iter1 = iter
.clone()
.enumerate()
.filter(|(i, _)| i % 4 < 2)
.map(|(_, value)| value);
let iter2 = iter
.enumerate()
.filter(|(i, _)| i % 4 >= 2)
.map(|(_, value)| value);
(iter1, iter2)
}
fn main() {
let v = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let iter = v.iter();
let (iter1, iter2) = uninterleave(iter);
for value in iter1 {
print!("{} ", value);
}
println!();
for value in iter2 {
print!("{} ", value);
}
}
打印:
0 1 4 5 8 9
2 3 6 7
关于parsing - 将迭代器取消交错为两个单独的迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66164084/