可以将迭代器连接起来吗?

23
let vec = iter::repeat("don't satisfy condition 1") // iterator such as next() always "don't " satisfy condition 1"
    .take_while(|_| {
        satisfycondition1.satisfy() // true is condition 1 is satisfied else false
    })
    .collect();

这段代码创建了一个长度为n的向量,其中n等于条件1不被满足的次数。

现在我想创建一个长度为n + m的向量,其中n等于条件1不被满足的次数,m等于条件2不被满足的次数。

代码应该长成这个样子:

let vec = iter::repeat("dont't satisfy condition 1")
    .take_while(|_| {
        satisfycondition1.satisfy() 
    })
    .union(
        iter::repeat("has satisfed condition 1 but not 2 yet")
        .take_while(|_| {
            satisfycondition2.satisfy() 
        })
    )
    .collect();

我知道我可以创建两个向量然后连接它们,但这样做效率较低。

您可以使用此代码理解 repeat 的含义:

use  std::iter;

fn main() {
    let mut c = 0;
    let z: Vec<_> = iter::repeat("dont't satisfy condition 1")
        .take_while(|_| {
            c = c + 1;
            let rep = if c < 5 { true } else { false };
            rep
        })
        .collect();
    println!("------{:?}", z);
}
1个回答

38

看起来你需要使用std::iter::chain

use std::iter;

fn main() {
    let mut c = 0;
    let mut d = 5;
    let z: Vec<_> = iter::repeat("don't satisfy condition 1")
        .take_while(|_| {
            c = c + 1;
            let rep = if c < 5 { true } else { false };
            rep
            // this block can be simplified to
            // c += 1;
            // c < 5
            // Clippy warns about this
        })
        .chain(
            iter::repeat("satisfy condition 1 but not 2").take_while(|_| {
                d -= 1;
                d > 2
            }),
        )
        .collect();
    println!("------{:?}", z);
}

(Playground链接)

我不能评论你代码的语义,如果你想查看迭代器中哪些元素“满足条件1但不满足条件2”,那么这不是你所要做的。你需要使用std::iter::filter两次(一次满足条件1,一次不满足条件2)来实现。


我已经考虑了你的最后一段话,并通过将“满足条件1但不满足条件2”修改为“已经满足条件1但尚未满足条件2”进行了修改。 - Pierre-olivier Gendraud

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接