pub trait Itertools: Iterator {
Show 49 methods
fn interleave<J>(self, other: J) -> Interleave<Self, J::IntoIter>ⓘNotable traits for Interleave<I, J>impl<I, J> Iterator for Interleave<I, J>where
I: Iterator,
J: Iterator<Item = I::Item>, type Item = I::Item;
where
J: IntoIterator<Item = Self::Item>,
Self: Sized,
{ ... }
fn interleave_shortest<J>(
self,
other: J
) -> InterleaveShortest<Self, J::IntoIter>ⓘNotable traits for InterleaveShortest<I, J>impl<I, J> Iterator for InterleaveShortest<I, J>where
I: Iterator,
J: Iterator<Item = I::Item>, type Item = I::Item;
where
J: IntoIterator<Item = Self::Item>,
Self: Sized,
{ ... }
fn intersperse(self, element: Self::Item) -> Intersperse<Self>ⓘNotable traits for Intersperse<I>impl<I> Iterator for Intersperse<I>where
I: Iterator,
I::Item: Clone, type Item = I::Item;
where
Self: Sized,
Self::Item: Clone,
{ ... }
fn zip_longest<J>(self, other: J) -> ZipLongest<Self, J::IntoIter>ⓘNotable traits for ZipLongest<T, U>impl<T, U> Iterator for ZipLongest<T, U>where
T: Iterator,
U: Iterator, type Item = EitherOrBoth<T::Item, U::Item>;
where
J: IntoIterator,
Self: Sized,
{ ... }
fn zip_eq<J>(self, other: J) -> ZipEq<Self, J::IntoIter>ⓘNotable traits for ZipEq<I, J>impl<I, J> Iterator for ZipEq<I, J>where
I: Iterator,
J: Iterator, type Item = (I::Item, J::Item);
where
J: IntoIterator,
Self: Sized,
{ ... }
fn batching<B, F>(self, f: F) -> Batching<Self, F>ⓘNotable traits for Batching<I, F>impl<B, F, I> Iterator for Batching<I, F>where
I: Iterator,
F: FnMut(&mut I) -> Option<B>, type Item = B;
where
F: FnMut(&mut Self) -> Option<B>,
Self: Sized,
{ ... }
fn tuple_windows<T>(self) -> TupleWindows<Self, T>ⓘNotable traits for TupleWindows<I, T>impl<I, T> Iterator for TupleWindows<I, T>where
I: Iterator<Item = T::Item>,
T: TupleCollect + Clone,
T::Item: Clone, type Item = T;
where
Self: Sized + Iterator<Item = T::Item>,
T: TupleCollect,
T::Item: Clone,
{ ... }
fn tuples<T>(self) -> Tuples<Self, T>ⓘNotable traits for Tuples<I, T>impl<I, T> Iterator for Tuples<I, T>where
I: Iterator<Item = T::Item>,
T: TupleCollect, type Item = T;
where
Self: Sized + Iterator<Item = T::Item>,
T: TupleCollect,
{ ... }
fn step(self, n: usize) -> Step<Self>ⓘNotable traits for Step<I>impl<I> Iterator for Step<I>where
I: Iterator, type Item = I::Item;
where
Self: Sized,
{ ... }
fn map_into<R>(self) -> MapInto<Self, R>ⓘNotable traits for MapInto<I, R>impl<I, R> Iterator for MapInto<I, R>where
I: Iterator,
I::Item: Into<R>, type Item = R;
where
Self: Sized,
Self::Item: Into<R>,
{ ... }
fn map_results<F, T, U, E>(self, f: F) -> MapResults<Self, F>ⓘNotable traits for MapResults<I, F>impl<I, F, T, U, E> Iterator for MapResults<I, F>where
I: Iterator<Item = Result<T, E>>,
F: FnMut(T) -> U, type Item = Result<U, E>;
where
Self: Iterator<Item = Result<T, E>> + Sized,
F: FnMut(T) -> U,
{ ... }
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>ⓘNotable traits for MergeBy<I, J, F>impl<I, J, F> Iterator for MergeBy<I, J, F>where
I: Iterator,
J: Iterator<Item = I::Item>,
F: MergePredicate<I::Item>, type Item = I::Item;
where
Self: Sized,
J: IntoIterator<Item = Self::Item>,
F: FnMut(&Self::Item, &Self::Item) -> bool,
{ ... }
fn merge_join_by<J, F>(
self,
other: J,
cmp_fn: F
) -> MergeJoinBy<Self, J::IntoIter, F>ⓘNotable traits for MergeJoinBy<I, J, F>impl<I, J, F> Iterator for MergeJoinBy<I, J, F>where
I: Iterator,
J: Iterator,
F: FnMut(&I::Item, &J::Item) -> Ordering, type Item = EitherOrBoth<I::Item, J::Item>;
where
J: IntoIterator,
F: FnMut(&Self::Item, &J::Item) -> Ordering,
Self: Sized,
{ ... }
fn cartesian_product<J>(self, other: J) -> Product<Self, J::IntoIter>ⓘNotable traits for Product<I, J>impl<I, J> Iterator for Product<I, J>where
I: Iterator,
J: Clone + Iterator,
I::Item: Clone, type Item = (I::Item, J::Item);
where
Self: Sized,
Self::Item: Clone,
J: IntoIterator,
J::IntoIter: Clone,
{ ... }
fn coalesce<F>(self, f: F) -> Coalesce<Self, F>ⓘNotable traits for Coalesce<I, F>impl<I, F> Iterator for Coalesce<I, F>where
I: Iterator,
F: FnMut(I::Item, I::Item) -> Result<I::Item, (I::Item, I::Item)>, type Item = I::Item;
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>ⓘNotable traits for DedupBy<I, Pred>impl<I, Pred> Iterator for DedupBy<I, Pred>where
I: Iterator,
I::Item: PartialEq,
Pred: DedupPredicate<I::Item>, type Item = I::Item;
where
Self: Sized,
Cmp: FnMut(&Self::Item, &Self::Item) -> bool,
{ ... }
fn peeking_take_while<F>(
&mut self,
accept: F
) -> PeekingTakeWhile<'_, Self, F>ⓘNotable traits for PeekingTakeWhile<'a, I, F>impl<'a, I, F> Iterator for PeekingTakeWhile<'a, I, F>where
I: PeekingNext,
F: FnMut(&I::Item) -> bool, type Item = I::Item;
where
Self: Sized + PeekingNext,
F: FnMut(&Self::Item) -> bool,
{ ... }
fn take_while_ref<F>(&mut self, accept: F) -> TakeWhileRef<'_, Self, F>ⓘNotable traits for TakeWhileRef<'a, I, F>impl<'a, I, F> Iterator for TakeWhileRef<'a, I, F>where
I: Iterator + Clone,
F: FnMut(&I::Item) -> bool, type Item = I::Item;
where
Self: Clone,
F: FnMut(&Self::Item) -> bool,
{ ... }
fn while_some<A>(self) -> WhileSome<Self>ⓘNotable traits for WhileSome<I>impl<I, A> Iterator for WhileSome<I>where
I: Iterator<Item = Option<A>>, type Item = A;
where
Self: Sized + Iterator<Item = Option<A>>,
{ ... }
fn tuple_combinations<T>(self) -> TupleCombinations<Self, T>ⓘNotable traits for TupleCombinations<I, T>impl<I, T> Iterator for TupleCombinations<I, T>where
I: Iterator,
T: HasCombination<I>, type Item = T;
where
Self: Sized + Clone,
Self::Item: Clone,
T: HasCombination<Self>,
{ ... }
fn pad_using<F>(self, min: usize, f: F) -> PadUsing<Self, F>ⓘNotable traits for PadUsing<I, F>impl<I, F> Iterator for PadUsing<I, F>where
I: Iterator,
F: FnMut(usize) -> I::Item, type Item = I::Item;
where
Self: Sized,
F: FnMut(usize) -> Self::Item,
{ ... }
fn with_position(self) -> WithPosition<Self>ⓘNotable traits for WithPosition<I>impl<I: Iterator> Iterator for WithPosition<I> type Item = Position<I::Item>;
where
Self: Sized,
{ ... }
fn positions<P>(self, predicate: P) -> Positions<Self, P>ⓘNotable traits for Positions<I, F>impl<I, F> Iterator for Positions<I, F>where
I: Iterator,
F: FnMut(I::Item) -> bool, type Item = usize;
where
Self: Sized,
P: FnMut(Self::Item) -> bool,
{ ... }
fn update<F>(self, updater: F) -> Update<Self, F>ⓘNotable traits for Update<I, F>impl<I, F> Iterator for Update<I, F>where
I: Iterator,
F: FnMut(&mut I::Item), type Item = I::Item;
where
Self: Sized,
F: FnMut(&mut Self::Item),
{ ... }
fn next_tuple<T>(&mut self) -> Option<T>
where
Self: Sized + Iterator<Item = T::Item>,
T: TupleCollect,
{ ... }
fn collect_tuple<T>(self) -> Option<T>
where
Self: Sized + Iterator<Item = T::Item>,
T: TupleCollect,
{ ... }
fn find_position<P>(&mut self, pred: P) -> Option<(usize, Self::Item)>
where
P: FnMut(&Self::Item) -> bool,
{ ... }
fn all_equal(&mut self) -> bool
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,
Self: 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_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 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 exactly_one(self) -> Result<Self::Item, ExactlyOneError<Self>>
where
Self: Sized,
{ ... }
}
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
sourcefn interleave<J>(self, other: J) -> Interleave<Self, J::IntoIter>ⓘNotable traits for Interleave<I, J>impl<I, J> Iterator for Interleave<I, J>where
I: Iterator,
J: Iterator<Item = I::Item>, type Item = I::Item;
where
J: IntoIterator<Item = Self::Item>,
Self: Sized,
fn interleave<J>(self, other: J) -> Interleave<Self, J::IntoIter>ⓘNotable traits for Interleave<I, J>impl<I, J> Iterator for Interleave<I, J>where
I: Iterator,
J: Iterator<Item = I::Item>, type Item = I::Item;
where
J: IntoIterator<Item = Self::Item>,
Self: Sized,
I: Iterator,
J: Iterator<Item = I::Item>, type Item = I::Item;
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]);
sourcefn interleave_shortest<J>(
self,
other: J
) -> InterleaveShortest<Self, J::IntoIter>ⓘNotable traits for InterleaveShortest<I, J>impl<I, J> Iterator for InterleaveShortest<I, J>where
I: Iterator,
J: Iterator<Item = I::Item>, type Item = I::Item;
where
J: IntoIterator<Item = Self::Item>,
Self: Sized,
fn interleave_shortest<J>(
self,
other: J
) -> InterleaveShortest<Self, J::IntoIter>ⓘNotable traits for InterleaveShortest<I, J>impl<I, J> Iterator for InterleaveShortest<I, J>where
I: Iterator,
J: Iterator<Item = I::Item>, type Item = I::Item;
where
J: IntoIterator<Item = Self::Item>,
Self: Sized,
I: Iterator,
J: Iterator<Item = I::Item>, type Item = I::Item;
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]);
sourcefn intersperse(self, element: Self::Item) -> Intersperse<Self>ⓘNotable traits for Intersperse<I>impl<I> Iterator for Intersperse<I>where
I: Iterator,
I::Item: Clone, type Item = I::Item;
where
Self: Sized,
Self::Item: Clone,
fn intersperse(self, element: Self::Item) -> Intersperse<Self>ⓘNotable traits for Intersperse<I>impl<I> Iterator for Intersperse<I>where
I: Iterator,
I::Item: Clone, type Item = I::Item;
where
Self: Sized,
Self::Item: Clone,
I: Iterator,
I::Item: Clone, type Item = I::Item;
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]);
sourcefn zip_longest<J>(self, other: J) -> ZipLongest<Self, J::IntoIter>ⓘNotable traits for ZipLongest<T, U>impl<T, U> Iterator for ZipLongest<T, U>where
T: Iterator,
U: Iterator, type Item = EitherOrBoth<T::Item, U::Item>;
where
J: IntoIterator,
Self: Sized,
fn zip_longest<J>(self, other: J) -> ZipLongest<Self, J::IntoIter>ⓘNotable traits for ZipLongest<T, U>impl<T, U> Iterator for ZipLongest<T, U>where
T: Iterator,
U: Iterator, type Item = EitherOrBoth<T::Item, U::Item>;
where
J: IntoIterator,
Self: Sized,
T: Iterator,
U: Iterator, type Item = EitherOrBoth<T::Item, U::Item>;
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)]);
sourcefn zip_eq<J>(self, other: J) -> ZipEq<Self, J::IntoIter>ⓘNotable traits for ZipEq<I, J>impl<I, J> Iterator for ZipEq<I, J>where
I: Iterator,
J: Iterator, type Item = (I::Item, J::Item);
where
J: IntoIterator,
Self: Sized,
fn zip_eq<J>(self, other: J) -> ZipEq<Self, J::IntoIter>ⓘNotable traits for ZipEq<I, J>impl<I, J> Iterator for ZipEq<I, J>where
I: Iterator,
J: Iterator, type Item = (I::Item, J::Item);
where
J: IntoIterator,
Self: Sized,
I: Iterator,
J: Iterator, type Item = (I::Item, J::Item);
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.
sourcefn batching<B, F>(self, f: F) -> Batching<Self, F>ⓘNotable traits for Batching<I, F>impl<B, F, I> Iterator for Batching<I, F>where
I: Iterator,
F: FnMut(&mut I) -> Option<B>, type Item = B;
where
F: FnMut(&mut Self) -> Option<B>,
Self: Sized,
fn batching<B, F>(self, f: F) -> Batching<Self, F>ⓘNotable traits for Batching<I, F>impl<B, F, I> Iterator for Batching<I, F>where
I: Iterator,
F: FnMut(&mut I) -> Option<B>, type Item = B;
where
F: FnMut(&mut Self) -> Option<B>,
Self: Sized,
I: Iterator,
F: FnMut(&mut I) -> Option<B>, type Item = B;
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)]);
sourcefn tuple_windows<T>(self) -> TupleWindows<Self, T>ⓘNotable traits for TupleWindows<I, T>impl<I, T> Iterator for TupleWindows<I, T>where
I: Iterator<Item = T::Item>,
T: TupleCollect + Clone,
T::Item: Clone, type Item = T;
where
Self: Sized + Iterator<Item = T::Item>,
T: TupleCollect,
T::Item: Clone,
fn tuple_windows<T>(self) -> TupleWindows<Self, T>ⓘNotable traits for TupleWindows<I, T>impl<I, T> Iterator for TupleWindows<I, T>where
I: Iterator<Item = T::Item>,
T: TupleCollect + Clone,
T::Item: Clone, type Item = T;
where
Self: Sized + Iterator<Item = T::Item>,
T: TupleCollect,
T::Item: Clone,
I: Iterator<Item = T::Item>,
T: TupleCollect + Clone,
T::Item: Clone, type Item = T;
Return an iterator over all contiguous windows producing tuples of a specific size (up to 4).
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).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)]);
sourcefn tuples<T>(self) -> Tuples<Self, T>ⓘNotable traits for Tuples<I, T>impl<I, T> Iterator for Tuples<I, T>where
I: Iterator<Item = T::Item>,
T: TupleCollect, type Item = T;
where
Self: Sized + Iterator<Item = T::Item>,
T: TupleCollect,
fn tuples<T>(self) -> Tuples<Self, T>ⓘNotable traits for Tuples<I, T>impl<I, T> Iterator for Tuples<I, T>where
I: Iterator<Item = T::Item>,
T: TupleCollect, type Item = T;
where
Self: Sized + Iterator<Item = T::Item>,
T: TupleCollect,
I: Iterator<Item = T::Item>,
T: TupleCollect, type Item = T;
Return an iterator that groups the items in tuples of a specific size (up to 4).
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
.
sourcefn step(self, n: usize) -> Step<Self>ⓘNotable traits for Step<I>impl<I> Iterator for Step<I>where
I: Iterator, type Item = I::Item;
where
Self: Sized,
fn step(self, n: usize) -> Step<Self>ⓘNotable traits for Step<I>impl<I> Iterator for Step<I>where
I: Iterator, type Item = I::Item;
where
Self: Sized,
I: Iterator, type Item = I::Item;
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]);
sourcefn map_into<R>(self) -> MapInto<Self, R>ⓘNotable traits for MapInto<I, R>impl<I, R> Iterator for MapInto<I, R>where
I: Iterator,
I::Item: Into<R>, type Item = R;
where
Self: Sized,
Self::Item: Into<R>,
fn map_into<R>(self) -> MapInto<Self, R>ⓘNotable traits for MapInto<I, R>impl<I, R> Iterator for MapInto<I, R>where
I: Iterator,
I::Item: Into<R>, type Item = R;
where
Self: Sized,
Self::Item: Into<R>,
I: Iterator,
I::Item: Into<R>, type Item = R;
Convert each item of the iterator using the Into
trait.
use itertools::Itertools;
(1i32..42i32).map_into::<f64>().collect_vec();
sourcefn map_results<F, T, U, E>(self, f: F) -> MapResults<Self, F>ⓘNotable traits for MapResults<I, F>impl<I, F, T, U, E> Iterator for MapResults<I, F>where
I: Iterator<Item = Result<T, E>>,
F: FnMut(T) -> U, type Item = Result<U, E>;
where
Self: Iterator<Item = Result<T, E>> + Sized,
F: FnMut(T) -> U,
fn map_results<F, T, U, E>(self, f: F) -> MapResults<Self, F>ⓘNotable traits for MapResults<I, F>impl<I, F, T, U, E> Iterator for MapResults<I, F>where
I: Iterator<Item = Result<T, E>>,
F: FnMut(T) -> U, type Item = Result<U, E>;
where
Self: Iterator<Item = Result<T, E>> + Sized,
F: FnMut(T) -> U,
I: Iterator<Item = Result<T, E>>,
F: FnMut(T) -> U, type Item = Result<U, E>;
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_results(|i| i + 1);
itertools::assert_equal(it, vec![Ok(42), Err(false), Ok(12)]);
sourcefn merge<J>(self, other: J) -> Merge<Self, J::IntoIter>where
Self: Sized,
Self::Item: PartialOrd,
J: IntoIterator<Item = Self::Item>,
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(3);
let b = (0..11).step(5);
let it = a.merge(b);
itertools::assert_equal(it, vec![0, 0, 3, 5, 6, 9, 10]);
sourcefn merge_by<J, F>(self, other: J, is_first: F) -> MergeBy<Self, J::IntoIter, F>ⓘNotable traits for MergeBy<I, J, F>impl<I, J, F> Iterator for MergeBy<I, J, F>where
I: Iterator,
J: Iterator<Item = I::Item>,
F: MergePredicate<I::Item>, type Item = I::Item;
where
Self: Sized,
J: IntoIterator<Item = Self::Item>,
F: FnMut(&Self::Item, &Self::Item) -> bool,
fn merge_by<J, F>(self, other: J, is_first: F) -> MergeBy<Self, J::IntoIter, F>ⓘNotable traits for MergeBy<I, J, F>impl<I, J, F> Iterator for MergeBy<I, J, F>where
I: Iterator,
J: Iterator<Item = I::Item>,
F: MergePredicate<I::Item>, type Item = I::Item;
where
Self: Sized,
J: IntoIterator<Item = Self::Item>,
F: FnMut(&Self::Item, &Self::Item) -> bool,
I: Iterator,
J: Iterator<Item = I::Item>,
F: MergePredicate<I::Item>, type Item = I::Item;
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')]);
sourcefn merge_join_by<J, F>(
self,
other: J,
cmp_fn: F
) -> MergeJoinBy<Self, J::IntoIter, F>ⓘNotable traits for MergeJoinBy<I, J, F>impl<I, J, F> Iterator for MergeJoinBy<I, J, F>where
I: Iterator,
J: Iterator,
F: FnMut(&I::Item, &J::Item) -> Ordering, type Item = EitherOrBoth<I::Item, J::Item>;
where
J: IntoIterator,
F: FnMut(&Self::Item, &J::Item) -> Ordering,
Self: Sized,
fn merge_join_by<J, F>(
self,
other: J,
cmp_fn: F
) -> MergeJoinBy<Self, J::IntoIter, F>ⓘNotable traits for MergeJoinBy<I, J, F>impl<I, J, F> Iterator for MergeJoinBy<I, J, F>where
I: Iterator,
J: Iterator,
F: FnMut(&I::Item, &J::Item) -> Ordering, type Item = EitherOrBoth<I::Item, J::Item>;
where
J: IntoIterator,
F: FnMut(&Self::Item, &J::Item) -> Ordering,
Self: Sized,
I: Iterator,
J: Iterator,
F: FnMut(&I::Item, &J::Item) -> Ordering, type Item = EitherOrBoth<I::Item, J::Item>;
Create an iterator that merges items from both this and the specified iterator in ascending order.
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)
wheni < j
, and removei
from its source iterator - Emit
EitherOrBoth::Right(j)
wheni > j
, and removej
from its source iterator - Emit
EitherOrBoth::Both(i, j)
wheni == j
, and remove bothi
andj
from their respective source iterators
use itertools::Itertools;
use itertools::EitherOrBoth::{Left, Right, Both};
let ki = (0..10).step(3);
let ku = (0..10).step(5);
let ki_ku = ki.merge_join_by(ku, |i, j| i.cmp(j)).map(|either| {
match either {
Left(_) => "Ki",
Right(_) => "Ku",
Both(_, _) => "KiKu"
}
});
itertools::assert_equal(ki_ku, vec!["KiKu", "Ki", "Ku", "Ki", "Ki"]);
sourcefn cartesian_product<J>(self, other: J) -> Product<Self, J::IntoIter>ⓘNotable traits for Product<I, J>impl<I, J> Iterator for Product<I, J>where
I: Iterator,
J: Clone + Iterator,
I::Item: Clone, type Item = (I::Item, J::Item);
where
Self: Sized,
Self::Item: Clone,
J: IntoIterator,
J::IntoIter: Clone,
fn cartesian_product<J>(self, other: J) -> Product<Self, J::IntoIter>ⓘNotable traits for Product<I, J>impl<I, J> Iterator for Product<I, J>where
I: Iterator,
J: Clone + Iterator,
I::Item: Clone, type Item = (I::Item, J::Item);
where
Self: Sized,
Self::Item: Clone,
J: IntoIterator,
J::IntoIter: Clone,
I: Iterator,
J: Clone + Iterator,
I::Item: Clone, type Item = (I::Item, J::Item);
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, 'β')]);
sourcefn coalesce<F>(self, f: F) -> Coalesce<Self, F>ⓘNotable traits for Coalesce<I, F>impl<I, F> Iterator for Coalesce<I, F>where
I: Iterator,
F: FnMut(I::Item, I::Item) -> Result<I::Item, (I::Item, I::Item)>, type Item = I::Item;
where
Self: Sized,
F: FnMut(Self::Item, Self::Item) -> Result<Self::Item, (Self::Item, Self::Item)>,
fn coalesce<F>(self, f: F) -> Coalesce<Self, F>ⓘNotable traits for Coalesce<I, F>impl<I, F> Iterator for Coalesce<I, F>where
I: Iterator,
F: FnMut(I::Item, I::Item) -> Result<I::Item, (I::Item, I::Item)>, type Item = I::Item;
where
Self: Sized,
F: FnMut(Self::Item, Self::Item) -> Result<Self::Item, (Self::Item, Self::Item)>,
I: Iterator,
F: FnMut(I::Item, I::Item) -> Result<I::Item, (I::Item, I::Item)>, type Item = I::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.]);
sourcefn dedup(self) -> Dedup<Self>where
Self: Sized,
Self::Item: PartialEq,
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.]);
sourcefn dedup_by<Cmp>(self, cmp: Cmp) -> DedupBy<Self, Cmp>ⓘNotable traits for DedupBy<I, Pred>impl<I, Pred> Iterator for DedupBy<I, Pred>where
I: Iterator,
I::Item: PartialEq,
Pred: DedupPredicate<I::Item>, type Item = I::Item;
where
Self: Sized,
Cmp: FnMut(&Self::Item, &Self::Item) -> bool,
fn dedup_by<Cmp>(self, cmp: Cmp) -> DedupBy<Self, Cmp>ⓘNotable traits for DedupBy<I, Pred>impl<I, Pred> Iterator for DedupBy<I, Pred>where
I: Iterator,
I::Item: PartialEq,
Pred: DedupPredicate<I::Item>, type Item = I::Item;
where
Self: Sized,
Cmp: FnMut(&Self::Item, &Self::Item) -> bool,
I: Iterator,
I::Item: PartialEq,
Pred: DedupPredicate<I::Item>, type Item = I::Item;
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.)]);
sourcefn peeking_take_while<F>(&mut self, accept: F) -> PeekingTakeWhile<'_, Self, F>ⓘNotable traits for PeekingTakeWhile<'a, I, F>impl<'a, I, F> Iterator for PeekingTakeWhile<'a, I, F>where
I: PeekingNext,
F: FnMut(&I::Item) -> bool, type Item = I::Item;
where
Self: Sized + PeekingNext,
F: FnMut(&Self::Item) -> bool,
fn peeking_take_while<F>(&mut self, accept: F) -> PeekingTakeWhile<'_, Self, F>ⓘNotable traits for PeekingTakeWhile<'a, I, F>impl<'a, I, F> Iterator for PeekingTakeWhile<'a, I, F>where
I: PeekingNext,
F: FnMut(&I::Item) -> bool, type Item = I::Item;
where
Self: Sized + PeekingNext,
F: FnMut(&Self::Item) -> bool,
I: PeekingNext,
F: FnMut(&I::Item) -> bool, type Item = I::Item;
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.
sourcefn take_while_ref<F>(&mut self, accept: F) -> TakeWhileRef<'_, Self, F>ⓘNotable traits for TakeWhileRef<'a, I, F>impl<'a, I, F> Iterator for TakeWhileRef<'a, I, F>where
I: Iterator + Clone,
F: FnMut(&I::Item) -> bool, type Item = I::Item;
where
Self: Clone,
F: FnMut(&Self::Item) -> bool,
fn take_while_ref<F>(&mut self, accept: F) -> TakeWhileRef<'_, Self, F>ⓘNotable traits for TakeWhileRef<'a, I, F>impl<'a, I, F> Iterator for TakeWhileRef<'a, I, F>where
I: Iterator + Clone,
F: FnMut(&I::Item) -> bool, type Item = I::Item;
where
Self: Clone,
F: FnMut(&Self::Item) -> bool,
I: Iterator + Clone,
F: FnMut(&I::Item) -> bool, type Item = I::Item;
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'));
sourcefn while_some<A>(self) -> WhileSome<Self>ⓘNotable traits for WhileSome<I>impl<I, A> Iterator for WhileSome<I>where
I: Iterator<Item = Option<A>>, type Item = A;
where
Self: Sized + Iterator<Item = Option<A>>,
fn while_some<A>(self) -> WhileSome<Self>ⓘNotable traits for WhileSome<I>impl<I, A> Iterator for WhileSome<I>where
I: Iterator<Item = Option<A>>, type Item = A;
where
Self: Sized + Iterator<Item = Option<A>>,
I: Iterator<Item = Option<A>>, type Item = 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());
sourcefn tuple_combinations<T>(self) -> TupleCombinations<Self, T>ⓘNotable traits for TupleCombinations<I, T>impl<I, T> Iterator for TupleCombinations<I, T>where
I: Iterator,
T: HasCombination<I>, type Item = T;
where
Self: Sized + Clone,
Self::Item: Clone,
T: HasCombination<Self>,
fn tuple_combinations<T>(self) -> TupleCombinations<Self, T>ⓘNotable traits for TupleCombinations<I, T>impl<I, T> Iterator for TupleCombinations<I, T>where
I: Iterator,
T: HasCombination<I>, type Item = T;
where
Self: Sized + Clone,
Self::Item: Clone,
T: HasCombination<Self>,
I: Iterator,
T: HasCombination<I>, type Item = T;
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 4.
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)]);
sourcefn pad_using<F>(self, min: usize, f: F) -> PadUsing<Self, F>ⓘNotable traits for PadUsing<I, F>impl<I, F> Iterator for PadUsing<I, F>where
I: Iterator,
F: FnMut(usize) -> I::Item, type Item = I::Item;
where
Self: Sized,
F: FnMut(usize) -> Self::Item,
fn pad_using<F>(self, min: usize, f: F) -> PadUsing<Self, F>ⓘNotable traits for PadUsing<I, F>impl<I, F> Iterator for PadUsing<I, F>where
I: Iterator,
F: FnMut(usize) -> I::Item, type Item = I::Item;
where
Self: Sized,
F: FnMut(usize) -> Self::Item,
I: Iterator,
F: FnMut(usize) -> I::Item, type Item = I::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]);
sourcefn with_position(self) -> WithPosition<Self>ⓘNotable traits for WithPosition<I>impl<I: Iterator> Iterator for WithPosition<I> type Item = Position<I::Item>;
where
Self: Sized,
fn with_position(self) -> WithPosition<Self>ⓘNotable traits for WithPosition<I>impl<I: Iterator> Iterator for WithPosition<I> type Item = Position<I::Item>;
where
Self: Sized,
Return an iterator adaptor that wraps each element in 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)]);
sourcefn positions<P>(self, predicate: P) -> Positions<Self, P>ⓘNotable traits for Positions<I, F>impl<I, F> Iterator for Positions<I, F>where
I: Iterator,
F: FnMut(I::Item) -> bool, type Item = usize;
where
Self: Sized,
P: FnMut(Self::Item) -> bool,
fn positions<P>(self, predicate: P) -> Positions<Self, P>ⓘNotable traits for Positions<I, F>impl<I, F> Iterator for Positions<I, F>where
I: Iterator,
F: FnMut(I::Item) -> bool, type Item = usize;
where
Self: Sized,
P: FnMut(Self::Item) -> bool,
I: Iterator,
F: FnMut(I::Item) -> bool, type Item = usize;
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]);
sourcefn update<F>(self, updater: F) -> Update<Self, F>ⓘNotable traits for Update<I, F>impl<I, F> Iterator for Update<I, F>where
I: Iterator,
F: FnMut(&mut I::Item), type Item = I::Item;
where
Self: Sized,
F: FnMut(&mut Self::Item),
fn update<F>(self, updater: F) -> Update<Self, F>ⓘNotable traits for Update<I, F>impl<I, F> Iterator for Update<I, F>where
I: Iterator,
F: FnMut(&mut I::Item), type Item = I::Item;
where
Self: Sized,
F: FnMut(&mut Self::Item),
I: Iterator,
F: FnMut(&mut I::Item), type Item = I::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]]);
sourcefn next_tuple<T>(&mut self) -> Option<T>where
Self: Sized + Iterator<Item = T::Item>,
T: TupleCollect,
fn next_tuple<T>(&mut self) -> Option<T>where
Self: Sized + Iterator<Item = T::Item>,
T: TupleCollect,
Advances the iterator and returns the next items grouped in a tuple of a specific size (up to 4).
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());
sourcefn collect_tuple<T>(self) -> Option<T>where
Self: Sized + Iterator<Item = T::Item>,
T: TupleCollect,
fn collect_tuple<T>(self) -> Option<T>where
Self: Sized + Iterator<Item = T::Item>,
T: TupleCollect,
Collects all items from the iterator into a tuple of a specific size (up to 4).
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")
}
sourcefn find_position<P>(&mut self, pred: P) -> Option<(usize, Self::Item)>where
P: FnMut(&Self::Item) -> bool,
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, 'α')));
sourcefn all_equal(&mut self) -> boolwhere
Self: Sized,
Self::Item: PartialEq,
fn all_equal(&mut self) -> boolwhere
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());
sourcefn dropping(self, n: usize) -> Selfwhere
Self: Sized,
fn dropping(self, n: usize) -> Selfwhere
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.
sourcefn dropping_back(self, n: usize) -> Selfwhere
Self: Sized,
Self: DoubleEndedIterator,
fn dropping_back(self, n: usize) -> Selfwhere
Self: Sized,
Self: 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]);
sourcefn foreach<F>(self, f: F)where
F: FnMut(Self::Item),
Self: Sized,
fn foreach<F>(self, f: F)where
F: FnMut(Self::Item),
Self: Sized,
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]);
sourcefn concat(self) -> Self::Itemwhere
Self: Sized,
Self::Item: Extend<<<Self as Iterator>::Item as IntoIterator>::Item> + IntoIterator + Default,
fn concat(self) -> Self::Itemwhere
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]);
sourcefn set_from<'a, A: 'a, J>(&mut self, from: J) -> usizewhere
Self: Iterator<Item = &'a mut A>,
J: IntoIterator<Item = A>,
fn set_from<'a, A: 'a, J>(&mut self, from: J) -> usizewhere
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]);
sourcefn format(self, sep: &str) -> Format<'_, Self>where
Self: Sized,
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");
sourcefn 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 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");
sourcefn 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_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,
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_results(0, Add::add),
Ok(3)
);
assert!(
values.iter()
.map(|&x| if x >= 0 { Ok(x) } else { Err("Negative number") })
.fold_results(0, Add::add)
.is_err()
);
sourcefn 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 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_results
.
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));
sourcefn fold1<F>(self, f: F) -> Option<Self::Item>where
F: FnMut(Self::Item, Self::Item) -> Self::Item,
Self: Sized,
fn fold1<F>(self, f: F) -> Option<Self::Item>where
F: FnMut(Self::Item, Self::Item) -> Self::Item,
Self: Sized,
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);
sourcefn tree_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,
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 fold1
:
1 2 3 4 5 6 7
│ │ │ │ │ │ │
└─f─f─f─f─f─f
If f
is associative, prefer the normal fold1
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));
sourcefn fold_while<B, F>(&mut self, init: B, f: F) -> FoldWhile<B>where
Self: Sized,
F: FnMut(B, Self::Item) -> FoldWhile<B>,
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 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(_)
.
sourcefn sum1<S>(self) -> Option<S>where
Self: Sized,
S: Sum<Self::Item>,
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));
sourcefn product1<P>(self) -> Option<P>where
Self: Sized,
P: Product<Self::Item>,
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));
sourcefn 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_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]);
sourcefn minmax(self) -> MinMaxResult<Self::Item>where
Self: Sized,
Self::Item: PartialOrd,
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, wherex <= 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.
sourcefn minmax_by_key<K, F>(self, key: F) -> MinMaxResult<Self::Item>where
Self: Sized,
K: PartialOrd,
F: FnMut(&Self::Item) -> K,
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.
sourcefn minmax_by<F>(self, compare: F) -> MinMaxResult<Self::Item>where
Self: Sized,
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
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.
sourcefn exactly_one(self) -> Result<Self::Item, ExactlyOneError<Self>>where
Self: Sized,
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));