Возможно ли объединить итераторы?

#rust #iterator

#Ржавчина #итератор

Вопрос:

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

Ответ №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. Я учитываю ваш последний абзац, изменив «удовлетворяет условию 1, но не 2» на «выполнил условие 1, но еще не 2»