Module bi_altern

Source
Expand description

§BiAltern

The bi_altern module provides an iterator, BiAltern, for alternately traversing exactly 2 iterators.

§Usage

To use BiAltern, create a new instance with BiAltern::new(Iterator<Item>, Iterator<Item>), or from an Iterable<Item>, use Iterable<Item>::altern_with(Iterable<Item>).
The next method will then yield elements from the 2 iterators in a round-robin fashion until both iterators are exhausted.
BiAlternis more complete than crate::altern::VecAltern, and implements core::iter::traits::exact_size::ExactSizeIterator if both iterators implement it. Also, if both additionally implement DoubleEndedIterator, then so does BiAltern.

§Examples

use combin_iterator::altern::BiAltern;
let vec1 = vec![1, 3, 5, 6];
let vec2 = vec![2, 4];

// Create a BiAltern iterator and add individual iterators
let iter = BiAltern::new(vec1.iter(), vec2.iter());

assert_eq!(iter.collect::<Vec<_>>(), vec![&1, &2, &3, &4, &5, &6]);


// You can also build it in a line thanks to the trait:
use combin_iterator::altern::AlternWith;
let iter = vec1.iter().altern_with(vec2.iter());

assert_eq!(iter.collect::<Vec<_>>(), vec![&1, &2, &3, &4, &5, &6]);

§Common mistake

BiAltern like VecAlterncan be used to iter over more than 2 iterable by combining them with each other, but the number of iterable must be a power of 2. Otherwise the number of pass on each iterable will not be equal (but maybe it is waht you want). And even if the number of iterable is a number of two, the order need to be correct to have the result expected.

For example:

use combin_iterator::altern::BiAltern;
let vec1 = vec![1, 1, 1, 1];
let vec2 = vec![2, 2];
let vec3 = vec![3, 3, 3];

// Here, `iter` will NOT be equivalent to
// vec![true, true, false, true ,true, false, true, false, true],
// but instead to vec![true, false, true, false, true, false, true, true, true].
// We alternate between BiAltern(vec1.iter(), vec2.iter()) and vec3.iter(),
// not between vec1.iter(), vec2.iter() and vec3.iter() at the same level.
let iter = BiAltern::new(BiAltern::new(vec1.iter(), vec2.iter()), vec3.iter());
assert_ne!(iter.collect::<Vec<_>>(), vec![&1, &2, &3, &1, &2, &3, &1, &3, &1]);

let iter = BiAltern::new(BiAltern::new(vec1.iter(), vec2.iter()), vec3.iter());
assert_eq!(iter.collect::<Vec<_>>(), vec![&1, &3, &2, &3, &1, &3, &2, &1, &1]);

// For the exact same reason:
use combin_iterator::altern::AlternWith;
let iter = vec1.iter().altern_with(vec2.iter()).altern_with(vec3.iter());
assert_ne!(iter.collect::<Vec<_>>(), vec![&1, &2, &3, &1, &2, &3, &1, &3, &1]);

let iter = vec1.iter().altern_with(vec2.iter()).altern_with(vec3.iter());
assert_eq!(iter.collect::<Vec<_>>(), vec![&1, &3, &2, &3, &1, &3, &2, &1, &1]);

// Now if we have 4 vec than we want to iterate over, we can at the same level:
let vec1 = vec![1, 1];
let vec2 = vec![2, 2];
let vec3 = vec![3, 3];
let vec4 = vec![4, 4];

// Notice: Don't use `altern_with`, otherwise they will never be at the same level, and the last iter will always be iter over one time of two.
let iter = BiAltern::new(BiAltern::new(vec1.iter(), vec2.iter()), BiAltern::new(vec3.iter(), vec4.iter()));

// Here, the order on wich we will iterate is: vec1.iter() -> vec3.iter() -> vec2.iter() -> vec4.iter() -> vec1.iter() -> ...
assert_eq!(iter.collect::<Vec<_>>(), vec![&1, &3, &2, &4, &1, &3, &2, &4]);

// If you want it to be vec1.iter() -> vec2.iter() -> vec3.iter() -> vec4.iter() -> vec1.iter() -> ...,
// then you should construct it like this:
let iter = BiAltern::new(BiAltern::new(vec1.iter(), vec3.iter()), BiAltern::new(vec2.iter(), vec4.iter()));
assert_eq!(iter.collect::<Vec<_>>(), vec![&1, &2, &3, &4, &1, &2, &3, &4]);

Structs§

BiAltern
BiAltern struct, to altern between 2 iterator.

Traits§

AlternWith
Trait to convert to a BiAltern iterator Implemented on Iterator