Можно ли объединить итераторы?

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();

Я знаю, что могу создать два вектора, а затем соединить их, но это менее эффективно.

Вы можете использовать этот код, чтобы понять, что повторяется:

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);
}
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
15
0
8 316
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, 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);
}

(ссылка на детскую площадку)

Однако я не могу комментировать семантику вашего кода. Если вы пытаетесь увидеть, какие элементы итератора «удовлетворяют условию 1, но не удовлетворяют условию 2», это будет не так. Вы должны использовать std::iter::filter дважды (один раз с условием 1 и один раз без условия 2), чтобы добиться этого.

Я принял во внимание ваш последний абзац, изменив «удовлетворяет условию 1, но не 2» на «удовлетворяет условию 1, но еще не 2».

Pierre-olivier Gendraud 11.04.2019 11:10

Другие вопросы по теме