Trait itertools::Itertools

source ·
pub trait Itertools: Iterator {
Show 76 methods // Provided methods fn interleave<J>(self, other: J) -> Interleave<Self, J::IntoIter> where J: IntoIterator<Item = Self::Item>, Self: Sized { ... } fn interleave_shortest<J>( self, other: J ) -> InterleaveShortest<Self, J::IntoIter> where J: IntoIterator<Item = Self::Item>, Self: Sized { ... } fn intersperse(self, element: Self::Item) -> Intersperse<Self> where Self: Sized, Self::Item: Clone { ... } fn intersperse_with<F>(self, element: F) -> IntersperseWith<Self, F> where Self: Sized, F: FnMut() -> Self::Item { ... } fn zip_longest<J>(self, other: J) -> ZipLongest<Self, J::IntoIter> where J: IntoIterator, Self: Sized { ... } fn zip_eq<J>(self, other: J) -> ZipEq<Self, J::IntoIter> where J: IntoIterator, Self: Sized { ... } fn batching<B, F>(self, f: F) -> Batching<Self, F> where F: FnMut(&mut Self) -> Option<B>, Self: Sized { ... } fn tuple_windows<T>(self) -> TupleWindows<Self, T> where Self: Sized + Iterator<Item = T::Item>, T: HomogeneousTuple, T::Item: Clone { ... } fn circular_tuple_windows<T>(self) -> CircularTupleWindows<Self, T> where Self: Sized + Clone + Iterator<Item = T::Item> + ExactSizeIterator, T: TupleCollect + Clone, T::Item: Clone { ... } fn tuples<T>(self) -> Tuples<Self, T> where Self: Sized + Iterator<Item = T::Item>, T: HomogeneousTuple { ... } fn step(self, n: usize) -> Step<Self> where Self: Sized { ... } fn map_into<R>(self) -> MapInto<Self, R> where Self: Sized, Self::Item: Into<R> { ... } fn map_results<F, T, U, E>(self, f: F) -> MapOk<Self, F> where Self: Iterator<Item = Result<T, E>> + Sized, F: FnMut(T) -> U { ... } fn map_ok<F, T, U, E>(self, f: F) -> MapOk<Self, F> where Self: Iterator<Item = Result<T, E>> + Sized, F: FnMut(T) -> U { ... } fn filter_ok<F, T, E>(self, f: F) -> FilterOk<Self, F> where Self: Iterator<Item = Result<T, E>> + Sized, F: FnMut(&T) -> bool { ... } fn filter_map_ok<F, T, U, E>(self, f: F) -> FilterMapOk<Self, F> where Self: Iterator<Item = Result<T, E>> + Sized, F: FnMut(T) -> Option<U> { ... } fn flatten_ok<T, E>(self) -> FlattenOk<Self, T, E> where Self: Iterator<Item = Result<T, E>> + Sized, T: IntoIterator { ... } fn process_results<F, T, E, R>(self, processor: F) -> Result<R, E> where Self: Iterator<Item = Result<T, E>> + Sized, F: FnOnce(ProcessResults<'_, Self, E>) -> R { ... } fn merge<J>(self, other: J) -> Merge<Self, J::IntoIter> where Self: Sized, Self::Item: PartialOrd, J: IntoIterator<Item = Self::Item> { ... } fn merge_by<J, F>( self, other: J, is_first: F ) -> MergeBy<Self, J::IntoIter, F> where Self: Sized, J: IntoIterator<Item = Self::Item>, F: FnMut(&Self::Item, &Self::Item) -> bool { ... } fn merge_join_by<J, F, T>( self, other: J, cmp_fn: F ) -> MergeJoinBy<Self, J::IntoIter, F> where J: IntoIterator, F: FnMut(&Self::Item, &J::Item) -> T, T: OrderingOrBool<Self::Item, J::Item>, Self: Sized { ... } fn cartesian_product<J>(self, other: J) -> Product<Self, J::IntoIter> where Self: Sized, Self::Item: Clone, J: IntoIterator, J::IntoIter: Clone { ... } fn coalesce<F>(self, f: F) -> Coalesce<Self, F> where Self: Sized, F: FnMut(Self::Item, Self::Item) -> Result<Self::Item, (Self::Item, Self::Item)> { ... } fn dedup(self) -> Dedup<Self> where Self: Sized, Self::Item: PartialEq { ... } fn dedup_by<Cmp>(self, cmp: Cmp) -> DedupBy<Self, Cmp> where Self: Sized, Cmp: FnMut(&Self::Item, &Self::Item) -> bool { ... } fn dedup_with_count(self) -> DedupWithCount<Self> where Self: Sized { ... } fn dedup_by_with_count<Cmp>(self, cmp: Cmp) -> DedupByWithCount<Self, Cmp> where Self: Sized, Cmp: FnMut(&Self::Item, &Self::Item) -> bool { ... } fn peeking_take_while<F>( &mut self, accept: F ) -> PeekingTakeWhile<'_, Self, F> where Self: Sized + PeekingNext, F: FnMut(&Self::Item) -> bool { ... } fn take_while_ref<F>(&mut self, accept: F) -> TakeWhileRef<'_, Self, F> where Self: Clone, F: FnMut(&Self::Item) -> bool { ... } fn take_while_inclusive<F>( &mut self, accept: F ) -> TakeWhileInclusive<'_, Self, F> where Self: Sized, F: FnMut(&Self::Item) -> bool { ... } fn while_some<A>(self) -> WhileSome<Self> where Self: Sized + Iterator<Item = Option<A>> { ... } fn tuple_combinations<T>(self) -> TupleCombinations<Self, T> where Self: Sized + Clone, Self::Item: Clone, T: HasCombination<Self> { ... } fn pad_using<F>(self, min: usize, f: F) -> PadUsing<Self, F> where Self: Sized, F: FnMut(usize) -> Self::Item { ... } fn with_position(self) -> WithPosition<Self> where Self: Sized { ... } fn positions<P>(self, predicate: P) -> Positions<Self, P> where Self: Sized, P: FnMut(Self::Item) -> bool { ... } fn update<F>(self, updater: F) -> Update<Self, F> where Self: Sized, F: FnMut(&mut Self::Item) { ... } fn next_tuple<T>(&mut self) -> Option<T> where Self: Sized + Iterator<Item = T::Item>, T: HomogeneousTuple { ... } fn collect_tuple<T>(self) -> Option<T> where Self: Sized + Iterator<Item = T::Item>, T: HomogeneousTuple { ... } fn find_position<P>(&mut self, pred: P) -> Option<(usize, Self::Item)> where P: FnMut(&Self::Item) -> bool { ... } fn find_or_last<P>(self, predicate: P) -> Option<Self::Item> where Self: Sized, P: FnMut(&Self::Item) -> bool { ... } fn find_or_first<P>(self, predicate: P) -> Option<Self::Item> where Self: Sized, P: FnMut(&Self::Item) -> bool { ... } fn contains<Q>(&mut self, query: &Q) -> bool where Self: Sized, Self::Item: Borrow<Q>, Q: PartialEq { ... } fn all_equal(&mut self) -> bool where Self: Sized, Self::Item: PartialEq { ... } fn all_equal_value( &mut self ) -> Result<Self::Item, Option<(Self::Item, Self::Item)>> where Self: Sized, Self::Item: PartialEq { ... } fn dropping(self, n: usize) -> Self where Self: Sized { ... } fn dropping_back(self, n: usize) -> Self where Self: Sized + DoubleEndedIterator { ... } fn foreach<F>(self, f: F) where F: FnMut(Self::Item), Self: Sized { ... } fn concat(self) -> Self::Item where Self: Sized, Self::Item: Extend<<<Self as Iterator>::Item as IntoIterator>::Item> + IntoIterator + Default { ... } fn set_from<'a, A: 'a, J>(&mut self, from: J) -> usize where Self: Iterator<Item = &'a mut A>, J: IntoIterator<Item = A> { ... } fn format(self, sep: &str) -> Format<'_, Self> where Self: Sized { ... } fn format_with<F>(self, sep: &str, format: F) -> FormatWith<'_, Self, F> where Self: Sized, F: FnMut(Self::Item, &mut dyn FnMut(&dyn Display) -> Result) -> Result { ... } fn fold_results<A, E, B, F>(&mut self, start: B, f: F) -> Result<B, E> where Self: Iterator<Item = Result<A, E>>, F: FnMut(B, A) -> B { ... } fn fold_ok<A, E, B, F>(&mut self, start: B, f: F) -> Result<B, E> where Self: Iterator<Item = Result<A, E>>, F: FnMut(B, A) -> B { ... } fn fold_options<A, B, F>(&mut self, start: B, f: F) -> Option<B> where Self: Iterator<Item = Option<A>>, F: FnMut(B, A) -> B { ... } fn fold1<F>(self, f: F) -> Option<Self::Item> where F: FnMut(Self::Item, Self::Item) -> Self::Item, Self: Sized { ... } fn tree_fold1<F>(self, f: F) -> Option<Self::Item> where F: FnMut(Self::Item, Self::Item) -> Self::Item, Self: Sized { ... } fn fold_while<B, F>(&mut self, init: B, f: F) -> FoldWhile<B> where Self: Sized, F: FnMut(B, Self::Item) -> FoldWhile<B> { ... } fn sum1<S>(self) -> Option<S> where Self: Sized, S: Sum<Self::Item> { ... } fn product1<P>(self) -> Option<P> where Self: Sized, P: Product<Self::Item> { ... } fn partition_map<A, B, F, L, R>(self, predicate: F) -> (A, B) where Self: Sized, F: FnMut(Self::Item) -> Either<L, R>, A: Default + Extend<L>, B: Default + Extend<R> { ... } fn partition_result<A, B, T, E>(self) -> (A, B) where Self: Iterator<Item = Result<T, E>> + Sized, A: Default + Extend<T>, B: Default + Extend<E> { ... } fn minmax(self) -> MinMaxResult<Self::Item> where Self: Sized, Self::Item: PartialOrd { ... } fn minmax_by_key<K, F>(self, key: F) -> MinMaxResult<Self::Item> where Self: Sized, K: PartialOrd, F: FnMut(&Self::Item) -> K { ... } fn minmax_by<F>(self, compare: F) -> MinMaxResult<Self::Item> where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering { ... } fn position_max(self) -> Option<usize> where Self: Sized, Self::Item: Ord { ... } fn position_max_by_key<K, F>(self, key: F) -> Option<usize> where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K { ... } fn position_max_by<F>(self, compare: F) -> Option<usize> where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering { ... } fn position_min(self) -> Option<usize> where Self: Sized, Self::Item: Ord { ... } fn position_min_by_key<K, F>(self, key: F) -> Option<usize> where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K { ... } fn position_min_by<F>(self, compare: F) -> Option<usize> where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering { ... } fn position_minmax(self) -> MinMaxResult<usize> where Self: Sized, Self::Item: PartialOrd { ... } fn position_minmax_by_key<K, F>(self, key: F) -> MinMaxResult<usize> where Self: Sized, K: PartialOrd, F: FnMut(&Self::Item) -> K { ... } fn position_minmax_by<F>(self, compare: F) -> MinMaxResult<usize> where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering { ... } fn exactly_one(self) -> Result<Self::Item, ExactlyOneError<Self>> where Self: Sized { ... } fn at_most_one(self) -> Result<Option<Self::Item>, ExactlyOneError<Self>> where Self: Sized { ... } fn multiunzip<FromI>(self) -> FromI where Self: Sized + MultiUnzip<FromI> { ... }
}
Expand description

An Iterator blanket implementation that provides extra adaptors and methods.

This trait defines a number of methods. They are divided into two groups:

  • Adaptors take an iterator and parameter as input, and return a new iterator value. These are listed first in the trait. An example of an adaptor is .interleave()

  • Regular methods are those that don’t return iterators and instead return a regular value of some other kind. .next_tuple() is an example and the first regular method in the list.

Provided Methods§

source

fn interleave<J>(self, other: J) -> Interleave<Self, J::IntoIter>
where J: IntoIterator<Item = Self::Item>, Self: Sized,

Alternate elements from two iterators until both have run out.

Iterator element type is Self::Item.

This iterator is fused.

use itertools::Itertools;

let it = (1..7).interleave(vec![-1, -2]);
itertools::assert_equal(it, vec![1, -1, 2, -2, 3, 4, 5, 6]);
source

fn interleave_shortest<J>( self, other: J ) -> InterleaveShortest<Self, J::IntoIter>
where J: IntoIterator<Item = Self::Item>, Self: Sized,

Alternate elements from two iterators until at least one of them has run out.

Iterator element type is Self::Item.

use itertools::Itertools;

let it = (1..7).interleave_shortest(vec![-1, -2]);
itertools::assert_equal(it, vec![1, -1, 2, -2, 3]);
source

fn intersperse(self, element: Self::Item) -> Intersperse<Self>
where Self: Sized, Self::Item: Clone,

An iterator adaptor to insert a particular value between each element of the adapted iterator.

Iterator element type is Self::Item.

This iterator is fused.

use itertools::Itertools;

itertools::assert_equal((0..3).intersperse(8), vec![0, 8, 1, 8, 2]);
source

fn intersperse_with<F>(self, element: F) -> IntersperseWith<Self, F>
where Self: Sized, F: FnMut() -> Self::Item,

An iterator adaptor to insert a particular value created by a function between each element of the adapted iterator.

Iterator element type is Self::Item.

This iterator is fused.

use itertools::Itertools;

let mut i = 10;
itertools::assert_equal((0..3).intersperse_with(|| { i -= 1; i }), vec![0, 9, 1, 8, 2]);
assert_eq!(i, 8);
source

fn zip_longest<J>(self, other: J) -> ZipLongest<Self, J::IntoIter>
where J: IntoIterator, Self: Sized,

Create an iterator which iterates over both this and the specified iterator simultaneously, yielding pairs of two optional elements.

This iterator is fused.

As long as neither input iterator is exhausted yet, it yields two values via EitherOrBoth::Both.

When the parameter iterator is exhausted, it only yields a value from the self iterator via EitherOrBoth::Left.

When the self iterator is exhausted, it only yields a value from the parameter iterator via EitherOrBoth::Right.

When both iterators return None, all further invocations of .next() will return None.

Iterator element type is EitherOrBoth<Self::Item, J::Item>.

use itertools::EitherOrBoth::{Both, Right};
use itertools::Itertools;
let it = (0..1).zip_longest(1..3);
itertools::assert_equal(it, vec![Both(0, 1), Right(2)]);
source

fn zip_eq<J>(self, other: J) -> ZipEq<Self, J::IntoIter>
where J: IntoIterator, Self: Sized,

Create an iterator which iterates over both this and the specified iterator simultaneously, yielding pairs of elements.

Panics if the iterators reach an end and they are not of equal lengths.

source

fn batching<B, F>(self, f: F) -> Batching<Self, F>
where F: FnMut(&mut Self) -> Option<B>, Self: Sized,

A “meta iterator adaptor”. Its closure receives a reference to the iterator and may pick off as many elements as it likes, to produce the next iterator element.

Iterator element type is B.

use itertools::Itertools;

// An adaptor that gathers elements in pairs
let pit = (0..4).batching(|it| {
           match it.next() {
               None => None,
               Some(x) => match it.next() {
                   None => None,
                   Some(y) => Some((x, y)),
               }
           }
       });

itertools::assert_equal(pit, vec![(0, 1), (2, 3)]);
source

fn tuple_windows<T>(self) -> TupleWindows<Self, T>
where Self: Sized + Iterator<Item = T::Item>, T: HomogeneousTuple, T::Item: Clone,

Return an iterator over all contiguous windows producing tuples of a specific size (up to 12).

tuple_windows clones the iterator elements so that they can be part of successive windows, this makes it most suited for iterators of references and other values that are cheap to copy.

use itertools::Itertools;
let mut v = Vec::new();

// pairwise iteration
for (a, b) in (1..5).tuple_windows() {
    v.push((a, b));
}
assert_eq!(v, vec![(1, 2), (2, 3), (3, 4)]);

let mut it = (1..5).tuple_windows();
assert_eq!(Some((1, 2, 3)), it.next());
assert_eq!(Some((2, 3, 4)), it.next());
assert_eq!(None, it.next());

// this requires a type hint
let it = (1..5).tuple_windows::<(_, _, _)>();
itertools::assert_equal(it, vec![(1, 2, 3), (2, 3, 4)]);

// you can also specify the complete type
use itertools::TupleWindows;
use std::ops::Range;

let it: TupleWindows<Range<u32>, (u32, u32, u32)> = (1..5).tuple_windows();
itertools::assert_equal(it, vec![(1, 2, 3), (2, 3, 4)]);
source

fn circular_tuple_windows<T>(self) -> CircularTupleWindows<Self, T>
where Self: Sized + Clone + Iterator<Item = T::Item> + ExactSizeIterator, T: TupleCollect + Clone, T::Item: Clone,

Return an iterator over all windows, wrapping back to the first elements when the window would otherwise exceed the length of the iterator, producing tuples of a specific size (up to 12).

circular_tuple_windows clones the iterator elements so that they can be part of successive windows, this makes it most suited for iterators of references and other values that are cheap to copy.

use itertools::Itertools;
let mut v = Vec::new();
for (a, b) in (1..5).circular_tuple_windows() {
    v.push((a, b));
}
assert_eq!(v, vec![(1, 2), (2, 3), (3, 4), (4, 1)]);

let mut it = (1..5).circular_tuple_windows();
assert_eq!(Some((1, 2, 3)), it.next());
assert_eq!(Some((2, 3, 4)), it.next());
assert_eq!(Some((3, 4, 1)), it.next());
assert_eq!(Some((4, 1, 2)), it.next());
assert_eq!(None, it.next());

// this requires a type hint
let it = (1..5).circular_tuple_windows::<(_, _, _)>();
itertools::assert_equal(it, vec![(1, 2, 3), (2, 3, 4), (3, 4, 1), (4, 1, 2)]);
source

fn tuples<T>(self) -> Tuples<Self, T>
where Self: Sized + Iterator<Item = T::Item>, T: HomogeneousTuple,

Return an iterator that groups the items in tuples of a specific size (up to 12).

See also the method .next_tuple().

use itertools::Itertools;
let mut v = Vec::new();
for (a, b) in (1..5).tuples() {
    v.push((a, b));
}
assert_eq!(v, vec![(1, 2), (3, 4)]);

let mut it = (1..7).tuples();
assert_eq!(Some((1, 2, 3)), it.next());
assert_eq!(Some((4, 5, 6)), it.next());
assert_eq!(None, it.next());

// this requires a type hint
let it = (1..7).tuples::<(_, _, _)>();
itertools::assert_equal(it, vec![(1, 2, 3), (4, 5, 6)]);

// you can also specify the complete type
use itertools::Tuples;
use std::ops::Range;

let it: Tuples<Range<u32>, (u32, u32, u32)> = (1..7).tuples();
itertools::assert_equal(it, vec![(1, 2, 3), (4, 5, 6)]);

See also Tuples::into_buffer.

source

fn step(self, n: usize) -> Step<Self>
where Self: Sized,

👎Deprecated since 0.8.0: Use std .step_by() instead

Return an iterator adaptor that steps n elements in the base iterator for each iteration.

The iterator steps by yielding the next element from the base iterator, then skipping forward n - 1 elements.

Iterator element type is Self::Item.

Panics if the step is 0.

use itertools::Itertools;

let it = (0..8).step(3);
itertools::assert_equal(it, vec![0, 3, 6]);
source

fn map_into<R>(self) -> MapInto<Self, R>
where Self: Sized, Self::Item: Into<R>,

Convert each item of the iterator using the Into trait.

use itertools::Itertools;

(1i32..42i32).map_into::<f64>().collect_vec();
source

fn map_results<F, T, U, E>(self, f: F) -> MapOk<Self, F>
where Self: Iterator<Item = Result<T, E>> + Sized, F: FnMut(T) -> U,

👎Deprecated since 0.10.0: Use .map_ok() instead

See .map_ok().

source

fn map_ok<F, T, U, E>(self, f: F) -> MapOk<Self, F>
where Self: Iterator<Item = Result<T, E>> + Sized, F: FnMut(T) -> U,

Return an iterator adaptor that applies the provided closure to every Result::Ok value. Result::Err values are unchanged.

use itertools::Itertools;

let input = vec![Ok(41), Err(false), Ok(11)];
let it = input.into_iter().map_ok(|i| i + 1);
itertools::assert_equal(it, vec![Ok(42), Err(false), Ok(12)]);
source

fn filter_ok<F, T, E>(self, f: F) -> FilterOk<Self, F>
where Self: Iterator<Item = Result<T, E>> + Sized, F: FnMut(&T) -> bool,

Return an iterator adaptor that filters every Result::Ok value with the provided closure. Result::Err values are unchanged.

use itertools::Itertools;

let input = vec![Ok(22), Err(false), Ok(11)];
let it = input.into_iter().filter_ok(|&i| i > 20);
itertools::assert_equal(it, vec![Ok(22), Err(false)]);
source

fn filter_map_ok<F, T, U, E>(self, f: F) -> FilterMapOk<Self, F>
where Self: Iterator<Item = Result<T, E>> + Sized, F: FnMut(T) -> Option<U>,

Return an iterator adaptor that filters and transforms every Result::Ok value with the provided closure. Result::Err values are unchanged.

use itertools::Itertools;

let input = vec![Ok(22), Err(false), Ok(11)];
let it = input.into_iter().filter_map_ok(|i| if i > 20 { Some(i * 2) } else { None });
itertools::assert_equal(it, vec![Ok(44), Err(false)]);
source

fn flatten_ok<T, E>(self) -> FlattenOk<Self, T, E>
where Self: Iterator<Item = Result<T, E>> + Sized, T: IntoIterator,

Return an iterator adaptor that flattens every Result::Ok value into a series of Result::Ok values. Result::Err values are unchanged.

This is useful when you have some common error type for your crate and need to propagate it upwards, but the Result::Ok case needs to be flattened.

use itertools::Itertools;

let input = vec![Ok(0..2), Err(false), Ok(2..4)];
let it = input.iter().cloned().flatten_ok();
itertools::assert_equal(it.clone(), vec![Ok(0), Ok(1), Err(false), Ok(2), Ok(3)]);

// This can also be used to propagate errors when collecting.
let output_result: Result<Vec<i32>, bool> = it.collect();
assert_eq!(output_result, Err(false));
source

fn process_results<F, T, E, R>(self, processor: F) -> Result<R, E>
where Self: Iterator<Item = Result<T, E>> + Sized, F: FnOnce(ProcessResults<'_, Self, E>) -> R,

“Lift” a function of the values of the current iterator so as to process an iterator of Result values instead.

processor is a closure that receives an adapted version of the iterator as the only argument — the adapted iterator produces elements of type T, as long as the original iterator produces Ok values.

If the original iterable produces an error at any point, the adapted iterator ends and it will return the error iself.

Otherwise, the return value from the closure is returned wrapped inside Ok.

§Example
use itertools::Itertools;

type Item = Result<i32, &'static str>;

let first_values: Vec<Item> = vec![Ok(1), Ok(0), Ok(3)];
let second_values: Vec<Item> = vec![Ok(2), Ok(1), Err("overflow")];

// “Lift” the iterator .max() method to work on the Ok-values.
let first_max = first_values.into_iter().process_results(|iter| iter.max().unwrap_or(0));
let second_max = second_values.into_iter().process_results(|iter| iter.max().unwrap_or(0));

assert_eq!(first_max, Ok(3));
assert!(second_max.is_err());
source

fn merge<J>(self, other: J) -> Merge<Self, J::IntoIter>
where Self: Sized, Self::Item: PartialOrd, J: IntoIterator<Item = Self::Item>,

Return an iterator adaptor that merges the two base iterators in ascending order. If both base iterators are sorted (ascending), the result is sorted.

Iterator element type is Self::Item.

use itertools::Itertools;

let a = (0..11).step_by(3);
let b = (0..11).step_by(5);
let it = a.merge(b);
itertools::assert_equal(it, vec![0, 0, 3, 5, 6, 9, 10]);
source

fn merge_by<J, F>(self, other: J, is_first: F) -> MergeBy<Self, J::IntoIter, F>
where Self: Sized, J: IntoIterator<Item = Self::Item>, F: FnMut(&Self::Item, &Self::Item) -> bool,

Return an iterator adaptor that merges the two base iterators in order. This is much like .merge() but allows for a custom ordering.

This can be especially useful for sequences of tuples.

Iterator element type is Self::Item.

use itertools::Itertools;

let a = (0..).zip("bc".chars());
let b = (0..).zip("ad".chars());
let it = a.merge_by(b, |x, y| x.1 <= y.1);
itertools::assert_equal(it, vec![(0, 'a'), (0, 'b'), (1, 'c'), (1, 'd')]);
source

fn merge_join_by<J, F, T>( self, other: J, cmp_fn: F ) -> MergeJoinBy<Self, J::IntoIter, F>
where J: IntoIterator, F: FnMut(&Self::Item, &J::Item) -> T, T: OrderingOrBool<Self::Item, J::Item>, Self: Sized,

Create an iterator that merges items from both this and the specified iterator in ascending order.

The function can either return an Ordering variant or a boolean.

If cmp_fn returns Ordering, it chooses whether to pair elements based on the Ordering returned by the specified compare function. At any point, inspecting the tip of the iterators I and J as items i of type I::Item and j of type J::Item respectively, the resulting iterator will:

  • Emit EitherOrBoth::Left(i) when i < j, and remove i from its source iterator
  • Emit EitherOrBoth::Right(j) when i > j, and remove j from its source iterator
  • Emit EitherOrBoth::Both(i, j) when i == j, and remove both i and j from their respective source iterators
use itertools::Itertools;
use itertools::EitherOrBoth::{Left, Right, Both};

let a = vec![0, 2, 4, 6, 1].into_iter();
let b = (0..10).step_by(3);

itertools::assert_equal(
    a.merge_join_by(b, |i, j| i.cmp(j)),
    vec![Both(0, 0), Left(2), Right(3), Left(4), Both(6, 6), Left(1), Right(9)]
);

If cmp_fn returns bool, it chooses whether to pair elements based on the boolean returned by the specified function. At any point, inspecting the tip of the iterators I and J as items i of type I::Item and j of type J::Item respectively, the resulting iterator will:

  • Emit Either::Left(i) when true, and remove i from its source iterator
  • Emit Either::Right(j) when false, and remove j from its source iterator

It is similar to the Ordering case if the first argument is considered “less” than the second argument.

use itertools::Itertools;
use itertools::Either::{Left, Right};

let a = vec![0, 2, 4, 6, 1].into_iter();
let b = (0..10).step_by(3);

itertools::assert_equal(
    a.merge_join_by(b, |i, j| i <= j),
    vec![Left(0), Right(0), Left(2), Right(3), Left(4), Left(6), Left(1), Right(6), Right(9)]
);
source

fn cartesian_product<J>(self, other: J) -> Product<Self, J::IntoIter>
where Self: Sized, Self::Item: Clone, J: IntoIterator, J::IntoIter: Clone,

Return an iterator adaptor that iterates over the cartesian product of the element sets of two iterators self and J.

Iterator element type is (Self::Item, J::Item).

use itertools::Itertools;

let it = (0..2).cartesian_product("αβ".chars());
itertools::assert_equal(it, vec![(0, 'α'), (0, 'β'), (1, 'α'), (1, 'β')]);
source

fn coalesce<F>(self, f: F) -> Coalesce<Self, F>
where Self: Sized, F: FnMut(Self::Item, Self::Item) -> Result<Self::Item, (Self::Item, Self::Item)>,

Return an iterator adaptor that uses the passed-in closure to optionally merge together consecutive elements.

The closure f is passed two elements, previous and current and may return either (1) Ok(combined) to merge the two values or (2) Err((previous', current')) to indicate they can’t be merged. In (2), the value previous' is emitted by the iterator. Either (1) combined or (2) current' becomes the previous value when coalesce continues with the next pair of elements to merge. The value that remains at the end is also emitted by the iterator.

Iterator element type is Self::Item.

This iterator is fused.

use itertools::Itertools;

// sum same-sign runs together
let data = vec![-1., -2., -3., 3., 1., 0., -1.];
itertools::assert_equal(data.into_iter().coalesce(|x, y|
        if (x >= 0.) == (y >= 0.) {
            Ok(x + y)
        } else {
            Err((x, y))
        }),
        vec![-6., 4., -1.]);
source

fn dedup(self) -> Dedup<Self>
where Self: Sized, Self::Item: PartialEq,

Remove duplicates from sections of consecutive identical elements. If the iterator is sorted, all elements will be unique.

Iterator element type is Self::Item.

This iterator is fused.

use itertools::Itertools;

let data = vec![1., 1., 2., 3., 3., 2., 2.];
itertools::assert_equal(data.into_iter().dedup(),
                        vec![1., 2., 3., 2.]);
source

fn dedup_by<Cmp>(self, cmp: Cmp) -> DedupBy<Self, Cmp>
where Self: Sized, Cmp: FnMut(&Self::Item, &Self::Item) -> bool,

Remove duplicates from sections of consecutive identical elements, determining equality using a comparison function. If the iterator is sorted, all elements will be unique.

Iterator element type is Self::Item.

This iterator is fused.

use itertools::Itertools;

let data = vec![(0, 1.), (1, 1.), (0, 2.), (0, 3.), (1, 3.), (1, 2.), (2, 2.)];
itertools::assert_equal(data.into_iter().dedup_by(|x, y| x.1 == y.1),
                        vec![(0, 1.), (0, 2.), (0, 3.), (1, 2.)]);
source

fn dedup_with_count(self) -> DedupWithCount<Self>
where Self: Sized,

Remove duplicates from sections of consecutive identical elements, while keeping a count of how many repeated elements were present. If the iterator is sorted, all elements will be unique.

Iterator element type is (usize, Self::Item).

This iterator is fused.

use itertools::Itertools;

let data = vec!['a', 'a', 'b', 'c', 'c', 'b', 'b'];
itertools::assert_equal(data.into_iter().dedup_with_count(),
                        vec![(2, 'a'), (1, 'b'), (2, 'c'), (2, 'b')]);
source

fn dedup_by_with_count<Cmp>(self, cmp: Cmp) -> DedupByWithCount<Self, Cmp>
where Self: Sized, Cmp: FnMut(&Self::Item, &Self::Item) -> bool,

Remove duplicates from sections of consecutive identical elements, while keeping a count of how many repeated elements were present. This will determine equality using a comparison function. If the iterator is sorted, all elements will be unique.

Iterator element type is (usize, Self::Item).

This iterator is fused.

use itertools::Itertools;

let data = vec![(0, 'a'), (1, 'a'), (0, 'b'), (0, 'c'), (1, 'c'), (1, 'b'), (2, 'b')];
itertools::assert_equal(data.into_iter().dedup_by_with_count(|x, y| x.1 == y.1),
                        vec![(2, (0, 'a')), (1, (0, 'b')), (2, (0, 'c')), (2, (1, 'b'))]);
source

fn peeking_take_while<F>(&mut self, accept: F) -> PeekingTakeWhile<'_, Self, F>
where Self: Sized + PeekingNext, F: FnMut(&Self::Item) -> bool,

Return an iterator adaptor that borrows from this iterator and takes items while the closure accept returns true.

This adaptor can only be used on iterators that implement PeekingNext like .peekable(), put_back and a few other collection iterators.

The last and rejected element (first false) is still available when peeking_take_while is done.

See also .take_while_ref() which is a similar adaptor.

source

fn take_while_ref<F>(&mut self, accept: F) -> TakeWhileRef<'_, Self, F>
where Self: Clone, F: FnMut(&Self::Item) -> bool,

Return an iterator adaptor that borrows from a Clone-able iterator to only pick off elements while the predicate accept returns true.

It uses the Clone trait to restore the original iterator so that the last and rejected element (first false) is still available when take_while_ref is done.

use itertools::Itertools;

let mut hexadecimals = "0123456789abcdef".chars();

let decimals = hexadecimals.take_while_ref(|c| c.is_numeric())
                           .collect::<String>();
assert_eq!(decimals, "0123456789");
assert_eq!(hexadecimals.next(), Some('a'));
source

fn take_while_inclusive<F>( &mut self, accept: F ) -> TakeWhileInclusive<'_, Self, F>
where Self: Sized, F: FnMut(&Self::Item) -> bool,

Returns an iterator adaptor that consumes elements while the given predicate is true, including the element for which the predicate first returned false.

The .take_while() adaptor is useful when you want items satisfying a predicate, but to know when to stop taking elements, we have to consume that first element that doesn’t satisfy the predicate. This adaptor includes that element where .take_while() would drop it.

The .take_while_ref() adaptor serves a similar purpose, but this adaptor doesn’t require Cloneing the underlying elements.

let items = vec![1, 2, 3, 4, 5];
let filtered: Vec<_> = items
    .into_iter()
    .take_while_inclusive(|&n| n % 3 != 0)
    .collect();

assert_eq!(filtered, vec![1, 2, 3]);
let items = vec![1, 2, 3, 4, 5];

let take_while_inclusive_result: Vec<_> = items
    .iter()
    .copied()
    .take_while_inclusive(|&n| n % 3 != 0)
    .collect();
let take_while_result: Vec<_> = items
    .into_iter()
    .take_while(|&n| n % 3 != 0)
    .collect();

assert_eq!(take_while_inclusive_result, vec![1, 2, 3]);
assert_eq!(take_while_result, vec![1, 2]);
// both iterators have the same items remaining at this point---the 3
// is lost from the `take_while` vec
#[derive(Debug, PartialEq)]
struct NoCloneImpl(i32);

let non_clonable_items: Vec<_> = vec![1, 2, 3, 4, 5]
    .into_iter()
    .map(NoCloneImpl)
    .collect();
let filtered: Vec<_> = non_clonable_items
    .into_iter()
    .take_while_inclusive(|n| n.0 % 3 != 0)
    .collect();
let expected: Vec<_> = vec![1, 2, 3].into_iter().map(NoCloneImpl).collect();
assert_eq!(filtered, expected);
source

fn while_some<A>(self) -> WhileSome<Self>
where Self: Sized + Iterator<Item = Option<A>>,

Return an iterator adaptor that filters Option<A> iterator elements and produces A. Stops on the first None encountered.

Iterator element type is A, the unwrapped element.

use itertools::Itertools;

// List all hexadecimal digits
itertools::assert_equal(
    (0..).map(|i| std::char::from_digit(i, 16)).while_some(),
    "0123456789abcdef".chars());
source

fn tuple_combinations<T>(self) -> TupleCombinations<Self, T>
where Self: Sized + Clone, Self::Item: Clone, T: HasCombination<Self>,

Return an iterator adaptor that iterates over the combinations of the elements from an iterator.

Iterator element can be any homogeneous tuple of type Self::Item with size up to 12.

use itertools::Itertools;

let mut v = Vec::new();
for (a, b) in (1..5).tuple_combinations() {
    v.push((a, b));
}
assert_eq!(v, vec![(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]);

let mut it = (1..5).tuple_combinations();
assert_eq!(Some((1, 2, 3)), it.next());
assert_eq!(Some((1, 2, 4)), it.next());
assert_eq!(Some((1, 3, 4)), it.next());
assert_eq!(Some((2, 3, 4)), it.next());
assert_eq!(None, it.next());

// this requires a type hint
let it = (1..5).tuple_combinations::<(_, _, _)>();
itertools::assert_equal(it, vec![(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]);

// you can also specify the complete type
use itertools::TupleCombinations;
use std::ops::Range;

let it: TupleCombinations<Range<u32>, (u32, u32, u32)> = (1..5).tuple_combinations();
itertools::assert_equal(it, vec![(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]);
source

fn pad_using<F>(self, min: usize, f: F) -> PadUsing<Self, F>
where Self: Sized, F: FnMut(usize) -> Self::Item,

Return an iterator adaptor that pads the sequence to a minimum length of min by filling missing elements using a closure f.

Iterator element type is Self::Item.

use itertools::Itertools;

let it = (0..5).pad_using(10, |i| 2*i);
itertools::assert_equal(it, vec![0, 1, 2, 3, 4, 10, 12, 14, 16, 18]);

let it = (0..10).pad_using(5, |i| 2*i);
itertools::assert_equal(it, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);

let it = (0..5).pad_using(10, |i| 2*i).rev();
itertools::assert_equal(it, vec![18, 16, 14, 12, 10, 4, 3, 2, 1, 0]);
source

fn with_position(self) -> WithPosition<Self>
where Self: Sized,

Return an iterator adaptor that combines each element with a Position to ease special-case handling of the first or last elements.

Iterator element type is (Position, Self::Item)

use itertools::{Itertools, Position};

let it = (0..4).with_position();
itertools::assert_equal(it,
                        vec![(Position::First, 0),
                             (Position::Middle, 1),
                             (Position::Middle, 2),
                             (Position::Last, 3)]);

let it = (0..1).with_position();
itertools::assert_equal(it, vec![(Position::Only, 0)]);
source

fn positions<P>(self, predicate: P) -> Positions<Self, P>
where Self: Sized, P: FnMut(Self::Item) -> bool,

Return an iterator adaptor that yields the indices of all elements satisfying a predicate, counted from the start of the iterator.

Equivalent to iter.enumerate().filter(|(_, v)| predicate(v)).map(|(i, _)| i).

use itertools::Itertools;

let data = vec![1, 2, 3, 3, 4, 6, 7, 9];
itertools::assert_equal(data.iter().positions(|v| v % 2 == 0), vec![1, 4, 5]);

itertools::assert_equal(data.iter().positions(|v| v % 2 == 1).rev(), vec![7, 6, 3, 2, 0]);
source

fn update<F>(self, updater: F) -> Update<Self, F>
where Self: Sized, F: FnMut(&mut Self::Item),

Return an iterator adaptor that applies a mutating function to each element before yielding it.

use itertools::Itertools;

let input = vec![vec![1], vec![3, 2, 1]];
let it = input.into_iter().update(|mut v| v.push(0));
itertools::assert_equal(it, vec![vec![1, 0], vec![3, 2, 1, 0]]);
source

fn next_tuple<T>(&mut self) -> Option<T>
where Self: Sized + Iterator<Item = T::Item>, T: HomogeneousTuple,

Advances the iterator and returns the next items grouped in a tuple of a specific size (up to 12).

If there are enough elements to be grouped in a tuple, then the tuple is returned inside Some, otherwise None is returned.

use itertools::Itertools;

let mut iter = 1..5;

assert_eq!(Some((1, 2)), iter.next_tuple());
source

fn collect_tuple<T>(self) -> Option<T>
where Self: Sized + Iterator<Item = T::Item>, T: HomogeneousTuple,

Collects all items from the iterator into a tuple of a specific size (up to 12).

If the number of elements inside the iterator is exactly equal to the tuple size, then the tuple is returned inside Some, otherwise None is returned.

use itertools::Itertools;

let iter = 1..3;

if let Some((x, y)) = iter.collect_tuple() {
    assert_eq!((x, y), (1, 2))
} else {
    panic!("Expected two elements")
}
source

fn find_position<P>(&mut self, pred: P) -> Option<(usize, Self::Item)>
where P: FnMut(&Self::Item) -> bool,

Find the position and value of the first element satisfying a predicate.

The iterator is not advanced past the first element found.

use itertools::Itertools;

let text = "Hα";
assert_eq!(text.chars().find_position(|ch| ch.is_lowercase()), Some((1, 'α')));
source

fn find_or_last<P>(self, predicate: P) -> Option<Self::Item>
where Self: Sized, P: FnMut(&Self::Item) -> bool,

Find the value of the first element satisfying a predicate or return the last element, if any.

The iterator is not advanced past the first element found.

use itertools::Itertools;

let numbers = [1, 2, 3, 4];
assert_eq!(numbers.iter().find_or_last(|&&x| x > 5), Some(&4));
assert_eq!(numbers.iter().find_or_last(|&&x| x > 2), Some(&3));
assert_eq!(std::iter::empty::<i32>().find_or_last(|&x| x > 5), None);
source

fn find_or_first<P>(self, predicate: P) -> Option<Self::Item>
where Self: Sized, P: FnMut(&Self::Item) -> bool,

Find the value of the first element satisfying a predicate or return the first element, if any.

The iterator is not advanced past the first element found.

use itertools::Itertools;

let numbers = [1, 2, 3, 4];
assert_eq!(numbers.iter().find_or_first(|&&x| x > 5), Some(&1));
assert_eq!(numbers.iter().find_or_first(|&&x| x > 2), Some(&3));
assert_eq!(std::iter::empty::<i32>().find_or_first(|&x| x > 5), None);
source

fn contains<Q>(&mut self, query: &Q) -> bool
where Self: Sized, Self::Item: Borrow<Q>, Q: PartialEq,

Returns true if the given item is present in this iterator.

This method is short-circuiting. If the given item is present in this iterator, this method will consume the iterator up-to-and-including the item. If the given item is not present in this iterator, the iterator will be exhausted.

use itertools::Itertools;

#[derive(PartialEq, Debug)]
enum Enum { A, B, C, D, E, }

let mut iter = vec![Enum::A, Enum::B, Enum::C, Enum::D].into_iter();

// search `iter` for `B`
assert_eq!(iter.contains(&Enum::B), true);
// `B` was found, so the iterator now rests at the item after `B` (i.e, `C`).
assert_eq!(iter.next(), Some(Enum::C));

// search `iter` for `E`
assert_eq!(iter.contains(&Enum::E), false);
// `E` wasn't found, so `iter` is now exhausted
assert_eq!(iter.next(), None);
source

fn all_equal(&mut self) -> bool
where Self: Sized, Self::Item: PartialEq,

Check whether all elements compare equal.

Empty iterators are considered to have equal elements:

use itertools::Itertools;

let data = vec![1, 1, 1, 2, 2, 3, 3, 3, 4, 5, 5];
assert!(!data.iter().all_equal());
assert!(data[0..3].iter().all_equal());
assert!(data[3..5].iter().all_equal());
assert!(data[5..8].iter().all_equal());

let data : Option<usize> = None;
assert!(data.into_iter().all_equal());
source

fn all_equal_value( &mut self ) -> Result<Self::Item, Option<(Self::Item, Self::Item)>>
where Self: Sized, Self::Item: PartialEq,

If there are elements and they are all equal, return a single copy of that element. If there are no elements, return an Error containing None. If there are elements and they are not all equal, return a tuple containing the first two non-equal elements found.

use itertools::Itertools;

let data = vec![1, 1, 1, 2, 2, 3, 3, 3, 4, 5, 5];
assert_eq!(data.iter().all_equal_value(), Err(Some((&1, &2))));
assert_eq!(data[0..3].iter().all_equal_value(), Ok(&1));
assert_eq!(data[3..5].iter().all_equal_value(), Ok(&2));
assert_eq!(data[5..8].iter().all_equal_value(), Ok(&3));

let data : Option<usize> = None;
assert_eq!(data.into_iter().all_equal_value(), Err(None));
source

fn dropping(self, n: usize) -> Self
where Self: Sized,

Consume the first n elements from the iterator eagerly, and return the same iterator again.

It works similarly to .skip( n ) except it is eager and preserves the iterator type.

use itertools::Itertools;

let mut iter = "αβγ".chars().dropping(2);
itertools::assert_equal(iter, "γ".chars());

Fusing notes: if the iterator is exhausted by dropping, the result of calling .next() again depends on the iterator implementation.

source

fn dropping_back(self, n: usize) -> Self
where Self: Sized + DoubleEndedIterator,

Consume the last n elements from the iterator eagerly, and return the same iterator again.

This is only possible on double ended iterators. n may be larger than the number of elements.

Note: This method is eager, dropping the back elements immediately and preserves the iterator type.

use itertools::Itertools;

let init = vec![0, 3, 6, 9].into_iter().dropping_back(1);
itertools::assert_equal(init, vec![0, 3, 6]);
source

fn foreach<F>(self, f: F)
where F: FnMut(Self::Item), Self: Sized,

👎Deprecated since 0.8.0: Use .for_each() instead

Run the closure f eagerly on each element of the iterator.

Consumes the iterator until its end.

use std::sync::mpsc::channel;
use itertools::Itertools;

let (tx, rx) = channel();

// use .foreach() to apply a function to each value -- sending it
(0..5).map(|x| x * 2 + 1).foreach(|x| { tx.send(x).unwrap(); } );

drop(tx);

itertools::assert_equal(rx.iter(), vec![1, 3, 5, 7, 9]);
source

fn concat(self) -> Self::Item
where Self: Sized, Self::Item: Extend<<<Self as Iterator>::Item as IntoIterator>::Item> + IntoIterator + Default,

Combine all an iterator’s elements into one element by using Extend.

This combinator will extend the first item with each of the rest of the items of the iterator. If the iterator is empty, the default value of I::Item is returned.

use itertools::Itertools;

let input = vec![vec![1], vec![2, 3], vec![4, 5, 6]];
assert_eq!(input.into_iter().concat(),
           vec![1, 2, 3, 4, 5, 6]);
source

fn set_from<'a, A: 'a, J>(&mut self, from: J) -> usize
where Self: Iterator<Item = &'a mut A>, J: IntoIterator<Item = A>,

Assign to each reference in self from the from iterator, stopping at the shortest of the two iterators.

The from iterator is queried for its next element before the self iterator, and if either is exhausted the method is done.

Return the number of elements written.

use itertools::Itertools;

let mut xs = [0; 4];
xs.iter_mut().set_from(1..);
assert_eq!(xs, [1, 2, 3, 4]);
source

fn format(self, sep: &str) -> Format<'_, Self>
where Self: Sized,

Format all iterator elements, separated by sep.

All elements are formatted (any formatting trait) with sep inserted between each element.

Panics if the formatter helper is formatted more than once.

use itertools::Itertools;

let data = [1.1, 2.71828, -3.];
assert_eq!(
    format!("{:.2}", data.iter().format(", ")),
           "1.10, 2.72, -3.00");
source

fn format_with<F>(self, sep: &str, format: F) -> FormatWith<'_, Self, F>
where Self: Sized, F: FnMut(Self::Item, &mut dyn FnMut(&dyn Display) -> Result) -> Result,

Format all iterator elements, separated by sep.

This is a customizable version of .format().

The supplied closure format is called once per iterator element, with two arguments: the element and a callback that takes a &Display value, i.e. any reference to type that implements Display.

Using &format_args!(...) is the most versatile way to apply custom element formatting. The callback can be called multiple times if needed.

Panics if the formatter helper is formatted more than once.

use itertools::Itertools;

let data = [1.1, 2.71828, -3.];
let data_formatter = data.iter().format_with(", ", |elt, f| f(&format_args!("{:.2}", elt)));
assert_eq!(format!("{}", data_formatter),
           "1.10, 2.72, -3.00");

// .format_with() is recursively composable
let matrix = [[1., 2., 3.],
              [4., 5., 6.]];
let matrix_formatter = matrix.iter().format_with("\n", |row, f| {
                                f(&row.iter().format_with(", ", |elt, g| g(&elt)))
                             });
assert_eq!(format!("{}", matrix_formatter),
           "1, 2, 3\n4, 5, 6");

source

fn fold_results<A, E, B, F>(&mut self, start: B, f: F) -> Result<B, E>
where Self: Iterator<Item = Result<A, E>>, F: FnMut(B, A) -> B,

👎Deprecated since 0.10.0: Use .fold_ok() instead
source

fn fold_ok<A, E, B, F>(&mut self, start: B, f: F) -> Result<B, E>
where Self: Iterator<Item = Result<A, E>>, F: FnMut(B, A) -> B,

Fold Result values from an iterator.

Only Ok values are folded. If no error is encountered, the folded value is returned inside Ok. Otherwise, the operation terminates and returns the first Err value it encounters. No iterator elements are consumed after the first error.

The first accumulator value is the start parameter. Each iteration passes the accumulator value and the next value inside Ok to the fold function f and its return value becomes the new accumulator value.

For example the sequence Ok(1), Ok(2), Ok(3) will result in a computation like this:

let mut accum = start;
accum = f(accum, 1);
accum = f(accum, 2);
accum = f(accum, 3);

With a start value of 0 and an addition as folding function, this effectively results in ((0 + 1) + 2) + 3

use std::ops::Add;
use itertools::Itertools;

let values = [1, 2, -2, -1, 2, 1];
assert_eq!(
    values.iter()
          .map(Ok::<_, ()>)
          .fold_ok(0, Add::add),
    Ok(3)
);
assert!(
    values.iter()
          .map(|&x| if x >= 0 { Ok(x) } else { Err("Negative number") })
          .fold_ok(0, Add::add)
          .is_err()
);
source

fn fold_options<A, B, F>(&mut self, start: B, f: F) -> Option<B>
where Self: Iterator<Item = Option<A>>, F: FnMut(B, A) -> B,

Fold Option values from an iterator.

Only Some values are folded. If no None is encountered, the folded value is returned inside Some. Otherwise, the operation terminates and returns None. No iterator elements are consumed after the None.

This is the Option equivalent to fold_ok.

use std::ops::Add;
use itertools::Itertools;

let mut values = vec![Some(1), Some(2), Some(-2)].into_iter();
assert_eq!(values.fold_options(5, Add::add), Some(5 + 1 + 2 - 2));

let mut more_values = vec![Some(2), None, Some(0)].into_iter();
assert!(more_values.fold_options(0, Add::add).is_none());
assert_eq!(more_values.next().unwrap(), Some(0));
source

fn fold1<F>(self, f: F) -> Option<Self::Item>
where F: FnMut(Self::Item, Self::Item) -> Self::Item, Self: Sized,

👎Deprecated since 0.10.2: Use Iterator::reduce instead

Accumulator of the elements in the iterator.

Like .fold(), without a base case. If the iterator is empty, return None. With just one element, return it. Otherwise elements are accumulated in sequence using the closure f.

use itertools::Itertools;

assert_eq!((0..10).fold1(|x, y| x + y).unwrap_or(0), 45);
assert_eq!((0..0).fold1(|x, y| x * y), None);
source

fn tree_fold1<F>(self, f: F) -> Option<Self::Item>
where F: FnMut(Self::Item, Self::Item) -> Self::Item, Self: Sized,

Accumulate the elements in the iterator in a tree-like manner.

You can think of it as, while there’s more than one item, repeatedly combining adjacent items. It does so in bottom-up-merge-sort order, however, so that it needs only logarithmic stack space.

This produces a call tree like the following (where the calls under an item are done after reading that item):

1 2 3 4 5 6 7
│ │ │ │ │ │ │
└─f └─f └─f │
  │   │   │ │
  └───f   └─f
      │     │
      └─────f

Which, for non-associative functions, will typically produce a different result than the linear call tree used by Iterator::reduce:

1 2 3 4 5 6 7
│ │ │ │ │ │ │
└─f─f─f─f─f─f

If f is associative, prefer the normal Iterator::reduce instead.

use itertools::Itertools;

// The same tree as above
let num_strings = (1..8).map(|x| x.to_string());
assert_eq!(num_strings.tree_fold1(|x, y| format!("f({}, {})", x, y)),
    Some(String::from("f(f(f(1, 2), f(3, 4)), f(f(5, 6), 7))")));

// Like fold1, an empty iterator produces None
assert_eq!((0..0).tree_fold1(|x, y| x * y), None);

// tree_fold1 matches fold1 for associative operations...
assert_eq!((0..10).tree_fold1(|x, y| x + y),
    (0..10).fold1(|x, y| x + y));
// ...but not for non-associative ones
assert_ne!((0..10).tree_fold1(|x, y| x - y),
    (0..10).fold1(|x, y| x - y));
source

fn fold_while<B, F>(&mut self, init: B, f: F) -> FoldWhile<B>
where Self: Sized, F: FnMut(B, Self::Item) -> FoldWhile<B>,

An iterator method that applies a function, producing a single, final value.

fold_while() is basically equivalent to Iterator::fold but with additional support for early exit via short-circuiting.

use itertools::Itertools;
use itertools::FoldWhile::{Continue, Done};

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

let mut result = 0;

// for loop:
for i in &numbers {
    if *i > 5 {
        break;
    }
    result = result + i;
}

// fold:
let result2 = numbers.iter().fold(0, |acc, x| {
    if *x > 5 { acc } else { acc + x }
});

// fold_while:
let result3 = numbers.iter().fold_while(0, |acc, x| {
    if *x > 5 { Done(acc) } else { Continue(acc + x) }
}).into_inner();

// they're the same
assert_eq!(result, result2);
assert_eq!(result2, result3);

The big difference between the computations of result2 and result3 is that while fold() called the provided closure for every item of the callee iterator, fold_while() actually stopped iterating as soon as it encountered Fold::Done(_).

source

fn sum1<S>(self) -> Option<S>
where Self: Sized, S: Sum<Self::Item>,

Iterate over the entire iterator and add all the elements.

An empty iterator returns None, otherwise Some(sum).

§Panics

When calling sum1() and a primitive integer type is being returned, this method will panic if the computation overflows and debug assertions are enabled.

§Examples
use itertools::Itertools;

let empty_sum = (1..1).sum1::<i32>();
assert_eq!(empty_sum, None);

let nonempty_sum = (1..11).sum1::<i32>();
assert_eq!(nonempty_sum, Some(55));
source

fn product1<P>(self) -> Option<P>
where Self: Sized, P: Product<Self::Item>,

Iterate over the entire iterator and multiply all the elements.

An empty iterator returns None, otherwise Some(product).

§Panics

When calling product1() and a primitive integer type is being returned, method will panic if the computation overflows and debug assertions are enabled.

§Examples
use itertools::Itertools;

let empty_product = (1..1).product1::<i32>();
assert_eq!(empty_product, None);

let nonempty_product = (1..11).product1::<i32>();
assert_eq!(nonempty_product, Some(3628800));
source

fn partition_map<A, B, F, L, R>(self, predicate: F) -> (A, B)
where Self: Sized, F: FnMut(Self::Item) -> Either<L, R>, A: Default + Extend<L>, B: Default + Extend<R>,

Collect all iterator elements into one of two partitions. Unlike Iterator::partition, each partition may have a distinct type.

use itertools::{Itertools, Either};

let successes_and_failures = vec![Ok(1), Err(false), Err(true), Ok(2)];

let (successes, failures): (Vec<_>, Vec<_>) = successes_and_failures
    .into_iter()
    .partition_map(|r| {
        match r {
            Ok(v) => Either::Left(v),
            Err(v) => Either::Right(v),
        }
    });

assert_eq!(successes, [1, 2]);
assert_eq!(failures, [false, true]);
source

fn partition_result<A, B, T, E>(self) -> (A, B)
where Self: Iterator<Item = Result<T, E>> + Sized, A: Default + Extend<T>, B: Default + Extend<E>,

Partition a sequence of Results into one list of all the Ok elements and another list of all the Err elements.

use itertools::Itertools;

let successes_and_failures = vec![Ok(1), Err(false), Err(true), Ok(2)];

let (successes, failures): (Vec<_>, Vec<_>) = successes_and_failures
    .into_iter()
    .partition_result();

assert_eq!(successes, [1, 2]);
assert_eq!(failures, [false, true]);
source

fn minmax(self) -> MinMaxResult<Self::Item>
where Self: Sized, Self::Item: PartialOrd,

Return the minimum and maximum elements in the iterator.

The return type MinMaxResult is an enum of three variants:

  • NoElements if the iterator is empty.
  • OneElement(x) if the iterator has exactly one element.
  • MinMax(x, y) is returned otherwise, where x <= y. Two values are equal if and only if there is more than one element in the iterator and all elements are equal.

On an iterator of length n, minmax does 1.5 * n comparisons, and so is faster than calling min and max separately which does 2 * n comparisons.

§Examples
use itertools::Itertools;
use itertools::MinMaxResult::{NoElements, OneElement, MinMax};

let a: [i32; 0] = [];
assert_eq!(a.iter().minmax(), NoElements);

let a = [1];
assert_eq!(a.iter().minmax(), OneElement(&1));

let a = [1, 2, 3, 4, 5];
assert_eq!(a.iter().minmax(), MinMax(&1, &5));

let a = [1, 1, 1, 1];
assert_eq!(a.iter().minmax(), MinMax(&1, &1));

The elements can be floats but no particular result is guaranteed if an element is NaN.

source

fn minmax_by_key<K, F>(self, key: F) -> MinMaxResult<Self::Item>
where Self: Sized, K: PartialOrd, F: FnMut(&Self::Item) -> K,

Return the minimum and maximum element of an iterator, as determined by the specified function.

The return value is a variant of MinMaxResult like for .minmax().

For the minimum, the first minimal element is returned. For the maximum, the last maximal element wins. This matches the behavior of the standard Iterator::min and Iterator::max methods.

The keys can be floats but no particular result is guaranteed if a key is NaN.

source

fn minmax_by<F>(self, compare: F) -> MinMaxResult<Self::Item>
where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Return the minimum and maximum element of an iterator, as determined by the specified comparison function.

The return value is a variant of MinMaxResult like for .minmax().

For the minimum, the first minimal element is returned. For the maximum, the last maximal element wins. This matches the behavior of the standard Iterator::min and Iterator::max methods.

source

fn position_max(self) -> Option<usize>
where Self: Sized, Self::Item: Ord,

Return the position of the maximum element in the iterator.

If several elements are equally maximum, the position of the last of them is returned.

§Examples
use itertools::Itertools;

let a: [i32; 0] = [];
assert_eq!(a.iter().position_max(), None);

let a = [-3, 0, 1, 5, -10];
assert_eq!(a.iter().position_max(), Some(3));

let a = [1, 1, -1, -1];
assert_eq!(a.iter().position_max(), Some(1));
source

fn position_max_by_key<K, F>(self, key: F) -> Option<usize>
where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K,

Return the position of the maximum element in the iterator, as determined by the specified function.

If several elements are equally maximum, the position of the last of them is returned.

§Examples
use itertools::Itertools;

let a: [i32; 0] = [];
assert_eq!(a.iter().position_max_by_key(|x| x.abs()), None);

let a = [-3_i32, 0, 1, 5, -10];
assert_eq!(a.iter().position_max_by_key(|x| x.abs()), Some(4));

let a = [1_i32, 1, -1, -1];
assert_eq!(a.iter().position_max_by_key(|x| x.abs()), Some(3));
source

fn position_max_by<F>(self, compare: F) -> Option<usize>
where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Return the position of the maximum element in the iterator, as determined by the specified comparison function.

If several elements are equally maximum, the position of the last of them is returned.

§Examples
use itertools::Itertools;

let a: [i32; 0] = [];
assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), None);

let a = [-3_i32, 0, 1, 5, -10];
assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), Some(3));

let a = [1_i32, 1, -1, -1];
assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), Some(1));
source

fn position_min(self) -> Option<usize>
where Self: Sized, Self::Item: Ord,

Return the position of the minimum element in the iterator.

If several elements are equally minimum, the position of the first of them is returned.

§Examples
use itertools::Itertools;

let a: [i32; 0] = [];
assert_eq!(a.iter().position_min(), None);

let a = [-3, 0, 1, 5, -10];
assert_eq!(a.iter().position_min(), Some(4));

let a = [1, 1, -1, -1];
assert_eq!(a.iter().position_min(), Some(2));
source

fn position_min_by_key<K, F>(self, key: F) -> Option<usize>
where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K,

Return the position of the minimum element in the iterator, as determined by the specified function.

If several elements are equally minimum, the position of the first of them is returned.

§Examples
use itertools::Itertools;

let a: [i32; 0] = [];
assert_eq!(a.iter().position_min_by_key(|x| x.abs()), None);

let a = [-3_i32, 0, 1, 5, -10];
assert_eq!(a.iter().position_min_by_key(|x| x.abs()), Some(1));

let a = [1_i32, 1, -1, -1];
assert_eq!(a.iter().position_min_by_key(|x| x.abs()), Some(0));
source

fn position_min_by<F>(self, compare: F) -> Option<usize>
where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Return the position of the minimum element in the iterator, as determined by the specified comparison function.

If several elements are equally minimum, the position of the first of them is returned.

§Examples
use itertools::Itertools;

let a: [i32; 0] = [];
assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), None);

let a = [-3_i32, 0, 1, 5, -10];
assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), Some(4));

let a = [1_i32, 1, -1, -1];
assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), Some(2));
source

fn position_minmax(self) -> MinMaxResult<usize>
where Self: Sized, Self::Item: PartialOrd,

Return the positions of the minimum and maximum elements in the iterator.

The return type MinMaxResult is an enum of three variants:

  • NoElements if the iterator is empty.
  • OneElement(xpos) if the iterator has exactly one element.
  • MinMax(xpos, ypos) is returned otherwise, where the element at xpos ≤ the element at ypos. While the referenced elements themselves may be equal, xpos cannot be equal to ypos.

On an iterator of length n, position_minmax does 1.5 * n comparisons, and so is faster than calling position_min and position_max separately which does 2 * n comparisons.

For the minimum, if several elements are equally minimum, the position of the first of them is returned. For the maximum, if several elements are equally maximum, the position of the last of them is returned.

The elements can be floats but no particular result is guaranteed if an element is NaN.

§Examples
use itertools::Itertools;
use itertools::MinMaxResult::{NoElements, OneElement, MinMax};

let a: [i32; 0] = [];
assert_eq!(a.iter().position_minmax(), NoElements);

let a = [10];
assert_eq!(a.iter().position_minmax(), OneElement(0));

let a = [-3, 0, 1, 5, -10];
assert_eq!(a.iter().position_minmax(), MinMax(4, 3));

let a = [1, 1, -1, -1];
assert_eq!(a.iter().position_minmax(), MinMax(2, 1));
source

fn position_minmax_by_key<K, F>(self, key: F) -> MinMaxResult<usize>
where Self: Sized, K: PartialOrd, F: FnMut(&Self::Item) -> K,

Return the postions of the minimum and maximum elements of an iterator, as determined by the specified function.

The return value is a variant of MinMaxResult like for position_minmax.

For the minimum, if several elements are equally minimum, the position of the first of them is returned. For the maximum, if several elements are equally maximum, the position of the last of them is returned.

The keys can be floats but no particular result is guaranteed if a key is NaN.

§Examples
use itertools::Itertools;
use itertools::MinMaxResult::{NoElements, OneElement, MinMax};

let a: [i32; 0] = [];
assert_eq!(a.iter().position_minmax_by_key(|x| x.abs()), NoElements);

let a = [10_i32];
assert_eq!(a.iter().position_minmax_by_key(|x| x.abs()), OneElement(0));

let a = [-3_i32, 0, 1, 5, -10];
assert_eq!(a.iter().position_minmax_by_key(|x| x.abs()), MinMax(1, 4));

let a = [1_i32, 1, -1, -1];
assert_eq!(a.iter().position_minmax_by_key(|x| x.abs()), MinMax(0, 3));
source

fn position_minmax_by<F>(self, compare: F) -> MinMaxResult<usize>
where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Return the postions of the minimum and maximum elements of an iterator, as determined by the specified comparison function.

The return value is a variant of MinMaxResult like for position_minmax.

For the minimum, if several elements are equally minimum, the position of the first of them is returned. For the maximum, if several elements are equally maximum, the position of the last of them is returned.

§Examples
use itertools::Itertools;
use itertools::MinMaxResult::{NoElements, OneElement, MinMax};

let a: [i32; 0] = [];
assert_eq!(a.iter().position_minmax_by(|x, y| x.cmp(y)), NoElements);

let a = [10_i32];
assert_eq!(a.iter().position_minmax_by(|x, y| x.cmp(y)), OneElement(0));

let a = [-3_i32, 0, 1, 5, -10];
assert_eq!(a.iter().position_minmax_by(|x, y| x.cmp(y)), MinMax(4, 3));

let a = [1_i32, 1, -1, -1];
assert_eq!(a.iter().position_minmax_by(|x, y| x.cmp(y)), MinMax(2, 1));
source

fn exactly_one(self) -> Result<Self::Item, ExactlyOneError<Self>>
where Self: Sized,

If the iterator yields exactly one element, that element will be returned, otherwise an error will be returned containing an iterator that has the same output as the input iterator.

This provides an additional layer of validation over just calling Iterator::next(). If your assumption that there should only be one element yielded is false this provides the opportunity to detect and handle that, preventing errors at a distance.

§Examples
use itertools::Itertools;

assert_eq!((0..10).filter(|&x| x == 2).exactly_one().unwrap(), 2);
assert!((0..10).filter(|&x| x > 1 && x < 4).exactly_one().unwrap_err().eq(2..4));
assert!((0..10).filter(|&x| x > 1 && x < 5).exactly_one().unwrap_err().eq(2..5));
assert!((0..10).filter(|&_| false).exactly_one().unwrap_err().eq(0..0));
source

fn at_most_one(self) -> Result<Option<Self::Item>, ExactlyOneError<Self>>
where Self: Sized,

If the iterator yields no elements, Ok(None) will be returned. If the iterator yields exactly one element, that element will be returned, otherwise an error will be returned containing an iterator that has the same output as the input iterator.

This provides an additional layer of validation over just calling Iterator::next(). If your assumption that there should be at most one element yielded is false this provides the opportunity to detect and handle that, preventing errors at a distance.

§Examples
use itertools::Itertools;

assert_eq!((0..10).filter(|&x| x == 2).at_most_one().unwrap(), Some(2));
assert!((0..10).filter(|&x| x > 1 && x < 4).at_most_one().unwrap_err().eq(2..4));
assert!((0..10).filter(|&x| x > 1 && x < 5).at_most_one().unwrap_err().eq(2..5));
assert_eq!((0..10).filter(|&_| false).at_most_one().unwrap(), None);
source

fn multiunzip<FromI>(self) -> FromI
where Self: Sized + MultiUnzip<FromI>,

Converts an iterator of tuples into a tuple of containers.

unzip() consumes an entire iterator of n-ary tuples, producing n collections, one for each column.

This function is, in some sense, the opposite of multizip.

use itertools::Itertools;

let inputs = vec![(1, 2, 3), (4, 5, 6), (7, 8, 9)];

let (a, b, c): (Vec<_>, Vec<_>, Vec<_>) = inputs
    .into_iter()
    .multiunzip();

assert_eq!(a, vec![1, 4, 7]);
assert_eq!(b, vec![2, 5, 8]);
assert_eq!(c, vec![3, 6, 9]);

Object Safety§

This trait is not object safe.

Implementors§

source§

impl<T> Itertools for T
where T: Iterator + ?Sized,