微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将迭代器拆分为两个独立的迭代器

如何解决将迭代器拆分为两个独立的迭代器

类似于这个问题: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,4,3,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 的块为 2 的迭代器。然后分块的迭代器将被分成另外两个迭代器。

从这个意义上说,我想将我的迭代器“解析”成 2 个块。

解决方法

如果原来的迭代器实现了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 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。