1 //! Licensed under the Apache License, Version 2.0
2 //! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
3 //! http://opensource.org/licenses/MIT, at your
4 //! option. This file may not be copied, modified, or distributed
5 //! except according to those terms.
8 #[cfg(feature = "use_std")]
9 pub use self::multi_product
::*;
12 use std
::mem
::replace
;
13 use std
::iter
::{Fuse, Peekable, FromIterator}
;
14 use std
::marker
::PhantomData
;
18 macro_rules
! clone_fields
{
19 ($name
:ident
, $base
:expr
, $
($field
:ident
),+) => (
22 $field
: $base
. $field
.clone()
28 /// An iterator adaptor that alternates elements from two iterators until both
31 /// This iterator is *fused*.
33 /// See [`.interleave()`](../trait.Itertools.html#method.interleave) for more information.
34 #[derive(Clone, Debug)]
35 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
36 pub struct Interleave
<I
, J
> {
42 /// Create an iterator that interleaves elements in `i` and `j`.
44 /// `IntoIterator` enabled version of `i.interleave(j)`.
47 /// use itertools::interleave;
49 /// for elt in interleave(&[1, 2, 3], &[2, 3, 4]) {
53 pub fn interleave
<I
, J
>(i
: I
, j
: J
) -> Interleave
<<I
as IntoIterator
>::IntoIter
, <J
as IntoIterator
>::IntoIter
>
54 where I
: IntoIterator
,
55 J
: IntoIterator
<Item
= I
::Item
>
58 a
: i
.into_iter().fuse(),
59 b
: j
.into_iter().fuse(),
64 impl<I
, J
> Iterator
for Interleave
<I
, J
>
66 J
: Iterator
<Item
= I
::Item
>
70 fn next(&mut self) -> Option
<I
::Item
> {
71 self.flag
= !self.flag
;
74 None
=> self.b
.next(),
79 None
=> self.a
.next(),
85 fn size_hint(&self) -> (usize, Option
<usize>) {
86 size_hint
::add(self.a
.size_hint(), self.b
.size_hint())
90 /// An iterator adaptor that alternates elements from the two iterators until
91 /// one of them runs out.
93 /// This iterator is *fused*.
95 /// See [`.interleave_shortest()`](../trait.Itertools.html#method.interleave_shortest)
96 /// for more information.
97 #[derive(Clone, Debug)]
98 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
99 pub struct InterleaveShortest
<I
, J
>
101 J
: Iterator
<Item
= I
::Item
>
105 phase
: bool
, // false ==> it0, true ==> it1
108 /// Create a new `InterleaveShortest` iterator.
109 pub fn interleave_shortest
<I
, J
>(a
: I
, b
: J
) -> InterleaveShortest
<I
, J
>
111 J
: Iterator
<Item
= I
::Item
>
120 impl<I
, J
> Iterator
for InterleaveShortest
<I
, J
>
122 J
: Iterator
<Item
= I
::Item
>
127 fn next(&mut self) -> Option
<I
::Item
> {
129 false => match self.it0
.next() {
136 true => match self.it1
.next() {
147 fn size_hint(&self) -> (usize, Option
<usize>) {
148 let (curr_hint
, next_hint
) = {
149 let it0_hint
= self.it0
.size_hint();
150 let it1_hint
= self.it1
.size_hint();
157 let (curr_lower
, curr_upper
) = curr_hint
;
158 let (next_lower
, next_upper
) = next_hint
;
159 let (combined_lower
, combined_upper
) =
160 size_hint
::mul_scalar(size_hint
::min(curr_hint
, next_hint
), 2);
162 if curr_lower
> next_lower
{
168 let extra_elem
= match (curr_upper
, next_upper
) {
170 (None
, Some(_
)) => true,
171 (Some(curr_max
), Some(next_max
)) => curr_max
> next_max
,
174 combined_upper
.and_then(|x
| x
.checked_add(1))
183 #[derive(Clone, Debug)]
184 /// An iterator adaptor that allows putting back a single
185 /// item to the front of the iterator.
187 /// Iterator element type is `I::Item`.
188 pub struct PutBack
<I
>
191 top
: Option
<I
::Item
>,
195 /// Create an iterator where you can put back a single item
196 pub fn put_back
<I
>(iterable
: I
) -> PutBack
<I
::IntoIter
>
197 where I
: IntoIterator
201 iter
: iterable
.into_iter(),
208 /// put back value `value` (builder method)
209 pub fn with_value(mut self, value
: I
::Item
) -> Self {
210 self.put_back(value
);
214 /// Split the `PutBack` into its parts.
216 pub fn into_parts(self) -> (Option
<I
::Item
>, I
) {
217 let PutBack{top, iter}
= self;
221 /// Put back a single value to the front of the iterator.
223 /// If a value is already in the put back slot, it is overwritten.
225 pub fn put_back(&mut self, x
: I
::Item
) {
230 impl<I
> Iterator
for PutBack
<I
>
235 fn next(&mut self) -> Option
<I
::Item
> {
237 None
=> self.iter
.next(),
238 ref mut some
=> some
.take(),
242 fn size_hint(&self) -> (usize, Option
<usize>) {
243 // Not ExactSizeIterator because size may be larger than usize
244 size_hint
::add_scalar(self.iter
.size_hint(), self.top
.is_some() as usize)
247 fn all
<G
>(&mut self, mut f
: G
) -> bool
248 where G
: FnMut(Self::Item
) -> bool
250 if let Some(elt
) = self.top
.take() {
258 fn fold
<Acc
, G
>(mut self, init
: Acc
, mut f
: G
) -> Acc
259 where G
: FnMut(Acc
, Self::Item
) -> Acc
,
261 let mut accum
= init
;
262 if let Some(elt
) = self.top
.take() {
263 accum
= f(accum
, elt
);
265 self.iter
.fold(accum
, f
)
269 #[derive(Debug, Clone)]
270 /// An iterator adaptor that iterates over the cartesian product of
271 /// the element sets of two iterators `I` and `J`.
273 /// Iterator element type is `(I::Item, J::Item)`.
275 /// See [`.cartesian_product()`](../trait.Itertools.html#method.cartesian_product) for more information.
276 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
277 pub struct Product
<I
, J
>
281 a_cur
: Option
<I
::Item
>,
286 /// Create a new cartesian product iterator
288 /// Iterator element type is `(I::Item, J::Item)`.
289 pub fn cartesian_product
<I
, J
>(mut i
: I
, j
: J
) -> Product
<I
, J
>
303 impl<I
, J
> Iterator
for Product
<I
, J
>
308 type Item
= (I
::Item
, J
::Item
);
309 fn next(&mut self) -> Option
<(I
::Item
, J
::Item
)> {
310 let elt_b
= match self.b
.next() {
312 self.b
= self.b_orig
.clone();
313 match self.b
.next() {
316 self.a_cur
= self.a
.next();
326 Some((a
.clone(), elt_b
))
331 fn size_hint(&self) -> (usize, Option
<usize>) {
332 let has_cur
= self.a_cur
.is_some() as usize;
333 // Not ExactSizeIterator because size may be larger than usize
334 let (b_min
, b_max
) = self.b
.size_hint();
336 // Compute a * b_orig + b for both lower and upper bound
338 size_hint
::mul(self.a
.size_hint(), self.b_orig
.size_hint()),
339 (b_min
* has_cur
, b_max
.map(move |x
| x
* has_cur
)))
342 fn fold
<Acc
, G
>(mut self, mut accum
: Acc
, mut f
: G
) -> Acc
343 where G
: FnMut(Acc
, Self::Item
) -> Acc
,
345 // use a split loop to handle the loose a_cur as well as avoiding to
346 // clone b_orig at the end.
347 if let Some(mut a
) = self.a_cur
.take() {
350 accum
= b
.fold(accum
, |acc
, elt
| f(acc
, (a
.clone(), elt
)));
352 // we can only continue iterating a if we had a first element;
353 if let Some(next_a
) = self.a
.next() {
354 b
= self.b_orig
.clone();
365 /// A “meta iterator adaptor”. Its closure recives a reference to the iterator
366 /// and may pick off as many elements as it likes, to produce the next iterator element.
368 /// Iterator element type is *X*, if the return type of `F` is *Option\<X\>*.
370 /// See [`.batching()`](../trait.Itertools.html#method.batching) for more information.
372 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
373 pub struct Batching
<I
, F
> {
378 impl<I
, F
> fmt
::Debug
for Batching
<I
, F
> where I
: fmt
::Debug
{
379 debug_fmt_fields
!(Batching
, iter
);
382 /// Create a new Batching iterator.
383 pub fn batching
<I
, F
>(iter
: I
, f
: F
) -> Batching
<I
, F
> {
384 Batching { f: f, iter: iter }
387 impl<B
, F
, I
> Iterator
for Batching
<I
, F
>
389 F
: FnMut(&mut I
) -> Option
<B
>
393 fn next(&mut self) -> Option
<B
> {
394 (self.f
)(&mut self.iter
)
398 fn size_hint(&self) -> (usize, Option
<usize>) {
399 // No information about closue behavior
404 /// An iterator adaptor that steps a number elements in the base iterator
405 /// for each iteration.
407 /// The iterator steps by yielding the next element from the base iterator,
408 /// then skipping forward *n-1* elements.
410 /// See [`.step()`](../trait.Itertools.html#method.step) for more information.
411 #[derive(Clone, Debug)]
412 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
418 /// Create a `Step` iterator.
420 /// **Panics** if the step is 0.
421 pub fn step
<I
>(iter
: I
, step
: usize) -> Step
<I
>
431 impl<I
> Iterator
for Step
<I
>
436 fn next(&mut self) -> Option
<I
::Item
> {
437 let elt
= self.iter
.next();
439 self.iter
.nth(self.skip
- 1);
444 fn size_hint(&self) -> (usize, Option
<usize>) {
445 let (low
, high
) = self.iter
.size_hint();
446 let div
= |x
: usize| {
450 1 + (x
- 1) / (self.skip
+ 1)
453 (div(low
), high
.map(div
))
458 impl<I
> ExactSizeIterator
for Step
<I
>
459 where I
: ExactSizeIterator
463 struct MergeCore
<I
, J
>
465 J
: Iterator
<Item
= I
::Item
>
473 impl<I
, J
> Clone
for MergeCore
<I
, J
>
475 J
: Iterator
<Item
= I
::Item
>,
479 fn clone(&self) -> Self {
480 clone_fields
!(MergeCore
, self, a
, b
, fused
)
484 impl<I
, J
> MergeCore
<I
, J
>
486 J
: Iterator
<Item
= I
::Item
>
488 fn next_with
<F
>(&mut self, mut less_than
: F
) -> Option
<I
::Item
>
489 where F
: FnMut(&I
::Item
, &I
::Item
) -> bool
491 let less_than
= match self.fused
{
493 None
=> match (self.a
.peek(), self.b
.peek()) {
494 (Some(a
), Some(b
)) => less_than(a
, b
),
496 self.fused
= Some(true);
500 self.fused
= Some(false);
503 (None
, None
) => return None
,
514 fn size_hint(&self) -> (usize, Option
<usize>) {
515 // Not ExactSizeIterator because size may be larger than usize
516 size_hint
::add(self.a
.size_hint(), self.b
.size_hint())
520 /// An iterator adaptor that merges the two base iterators in ascending order.
521 /// If both base iterators are sorted (ascending), the result is sorted.
523 /// Iterator element type is `I::Item`.
525 /// See [`.merge()`](../trait.Itertools.html#method.merge_by) for more information.
526 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
527 pub struct Merge
<I
, J
>
529 J
: Iterator
<Item
= I
::Item
>
531 merge
: MergeCore
<I
, J
>,
534 impl<I
, J
> Clone
for Merge
<I
, J
>
536 J
: Iterator
<Item
= I
::Item
>,
540 fn clone(&self) -> Self {
541 clone_fields
!(Merge
, self, merge
)
545 impl<I
, J
> fmt
::Debug
for Merge
<I
, J
>
546 where I
: Iterator
+ fmt
::Debug
, J
: Iterator
<Item
= I
::Item
> + fmt
::Debug
,
549 debug_fmt_fields
!(Merge
, merge
.a
, merge
.b
);
552 /// Create an iterator that merges elements in `i` and `j`.
554 /// `IntoIterator` enabled version of `i.merge(j)`.
557 /// use itertools::merge;
559 /// for elt in merge(&[1, 2, 3], &[2, 3, 4]) {
563 pub fn merge
<I
, J
>(i
: I
, j
: J
) -> Merge
<<I
as IntoIterator
>::IntoIter
, <J
as IntoIterator
>::IntoIter
>
564 where I
: IntoIterator
,
565 J
: IntoIterator
<Item
= I
::Item
>,
570 a
: i
.into_iter().peekable(),
571 b
: j
.into_iter().peekable(),
577 impl<I
, J
> Iterator
for Merge
<I
, J
>
579 J
: Iterator
<Item
= I
::Item
>,
584 fn next(&mut self) -> Option
<I
::Item
> {
585 self.merge
.next_with(|a
, b
| a
<= b
)
588 fn size_hint(&self) -> (usize, Option
<usize>) {
589 self.merge
.size_hint()
593 /// An iterator adaptor that merges the two base iterators in ascending order.
594 /// If both base iterators are sorted (ascending), the result is sorted.
596 /// Iterator element type is `I::Item`.
598 /// See [`.merge_by()`](../trait.Itertools.html#method.merge_by) for more information.
599 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
600 pub struct MergeBy
<I
, J
, F
>
602 J
: Iterator
<Item
= I
::Item
>
604 merge
: MergeCore
<I
, J
>,
608 impl<I
, J
, F
> fmt
::Debug
for MergeBy
<I
, J
, F
>
609 where I
: Iterator
+ fmt
::Debug
, J
: Iterator
<Item
= I
::Item
> + fmt
::Debug
,
612 debug_fmt_fields
!(MergeBy
, merge
.a
, merge
.b
);
615 /// Create a `MergeBy` iterator.
616 pub fn merge_by_new
<I
, J
, F
>(a
: I
, b
: J
, cmp
: F
) -> MergeBy
<I
, J
, F
>
618 J
: Iterator
<Item
= I
::Item
>
630 impl<I
, J
, F
> Clone
for MergeBy
<I
, J
, F
>
632 J
: Iterator
<Item
= I
::Item
>,
637 fn clone(&self) -> Self {
638 clone_fields
!(MergeBy
, self, merge
, cmp
)
642 impl<I
, J
, F
> Iterator
for MergeBy
<I
, J
, F
>
644 J
: Iterator
<Item
= I
::Item
>,
645 F
: FnMut(&I
::Item
, &I
::Item
) -> bool
649 fn next(&mut self) -> Option
<I
::Item
> {
650 self.merge
.next_with(&mut self.cmp
)
653 fn size_hint(&self) -> (usize, Option
<usize>) {
654 self.merge
.size_hint()
658 #[derive(Clone, Debug)]
659 pub struct CoalesceCore
<I
>
663 last
: Option
<I
::Item
>,
666 impl<I
> CoalesceCore
<I
>
669 fn next_with
<F
>(&mut self, mut f
: F
) -> Option
<I
::Item
>
670 where F
: FnMut(I
::Item
, I
::Item
) -> Result
<I
::Item
, (I
::Item
, I
::Item
)>
672 // this fuses the iterator
673 let mut last
= match self.last
.take() {
677 for next
in &mut self.iter
{
678 match f(last
, next
) {
679 Ok(joined
) => last
= joined
,
680 Err((last_
, next_
)) => {
681 self.last
= Some(next_
);
690 fn size_hint(&self) -> (usize, Option
<usize>) {
691 let (low
, hi
) = size_hint
::add_scalar(self.iter
.size_hint(),
692 self.last
.is_some() as usize);
693 ((low
> 0) as usize, hi
)
697 /// An iterator adaptor that may join together adjacent elements.
699 /// See [`.coalesce()`](../trait.Itertools.html#method.coalesce) for more information.
700 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
701 pub struct Coalesce
<I
, F
>
704 iter
: CoalesceCore
<I
>,
708 impl<I
: Clone
, F
: Clone
> Clone
for Coalesce
<I
, F
>
712 fn clone(&self) -> Self {
713 clone_fields
!(Coalesce
, self, iter
, f
)
717 impl<I
, F
> fmt
::Debug
for Coalesce
<I
, F
>
718 where I
: Iterator
+ fmt
::Debug
,
721 debug_fmt_fields
!(Coalesce
, iter
);
724 /// Create a new `Coalesce`.
725 pub fn coalesce
<I
, F
>(mut iter
: I
, f
: F
) -> Coalesce
<I
, F
>
737 impl<I
, F
> Iterator
for Coalesce
<I
, F
>
739 F
: FnMut(I
::Item
, I
::Item
) -> Result
<I
::Item
, (I
::Item
, I
::Item
)>
743 fn next(&mut self) -> Option
<I
::Item
> {
744 self.iter
.next_with(&mut self.f
)
747 fn size_hint(&self) -> (usize, Option
<usize>) {
748 self.iter
.size_hint()
752 /// An iterator adaptor that removes repeated duplicates.
754 /// See [`.dedup()`](../trait.Itertools.html#method.dedup) for more information.
755 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
759 iter
: CoalesceCore
<I
>,
762 impl<I
: Clone
> Clone
for Dedup
<I
>
766 fn clone(&self) -> Self {
767 clone_fields
!(Dedup
, self, iter
)
771 /// Create a new `Dedup`.
772 pub fn dedup
<I
>(mut iter
: I
) -> Dedup
<I
>
783 impl<I
> fmt
::Debug
for Dedup
<I
>
784 where I
: Iterator
+ fmt
::Debug
,
787 debug_fmt_fields
!(Dedup
, iter
);
790 impl<I
> Iterator
for Dedup
<I
>
796 fn next(&mut self) -> Option
<I
::Item
> {
797 self.iter
.next_with(|x
, y
| {
798 if x
== y { Ok(x) }
else { Err((x, y)) }
802 fn size_hint(&self) -> (usize, Option
<usize>) {
803 self.iter
.size_hint()
806 fn fold
<Acc
, G
>(self, mut accum
: Acc
, mut f
: G
) -> Acc
807 where G
: FnMut(Acc
, Self::Item
) -> Acc
,
809 if let Some(mut last
) = self.iter
.last
{
810 accum
= self.iter
.iter
.fold(accum
, |acc
, elt
| {
814 f(acc
, replace(&mut last
, elt
))
824 /// An iterator adaptor that borrows from a `Clone`-able iterator
825 /// to only pick off elements while the predicate returns `true`.
827 /// See [`.take_while_ref()`](../trait.Itertools.html#method.take_while_ref) for more information.
828 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
829 pub struct TakeWhileRef
<'a
, I
: 'a
, F
> {
834 impl<'a
, I
, F
> fmt
::Debug
for TakeWhileRef
<'a
, I
, F
>
835 where I
: Iterator
+ fmt
::Debug
,
837 debug_fmt_fields
!(TakeWhileRef
, iter
);
840 /// Create a new `TakeWhileRef` from a reference to clonable iterator.
841 pub fn take_while_ref
<I
, F
>(iter
: &mut I
, f
: F
) -> TakeWhileRef
<I
, F
>
842 where I
: Iterator
+ Clone
844 TakeWhileRef { iter: iter, f: f }
847 impl<'a
, I
, F
> Iterator
for TakeWhileRef
<'a
, I
, F
>
848 where I
: Iterator
+ Clone
,
849 F
: FnMut(&I
::Item
) -> bool
853 fn next(&mut self) -> Option
<I
::Item
> {
854 let old
= self.iter
.clone();
855 match self.iter
.next() {
868 fn size_hint(&self) -> (usize, Option
<usize>) {
869 let (_
, hi
) = self.iter
.size_hint();
874 /// An iterator adaptor that filters `Option<A>` iterator elements
875 /// and produces `A`. Stops on the first `None` encountered.
877 /// See [`.while_some()`](../trait.Itertools.html#method.while_some) for more information.
878 #[derive(Clone, Debug)]
879 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
880 pub struct WhileSome
<I
> {
884 /// Create a new `WhileSome<I>`.
885 pub fn while_some
<I
>(iter
: I
) -> WhileSome
<I
> {
886 WhileSome { iter: iter }
889 impl<I
, A
> Iterator
for WhileSome
<I
>
890 where I
: Iterator
<Item
= Option
<A
>>
894 fn next(&mut self) -> Option
<A
> {
895 match self.iter
.next() {
896 None
| Some(None
) => None
,
901 fn size_hint(&self) -> (usize, Option
<usize>) {
902 let sh
= self.iter
.size_hint();
907 /// An iterator to iterate through all combinations in a `Clone`-able iterator that produces tuples
908 /// of a specific size.
910 /// See [`.tuple_combinations()`](../trait.Itertools.html#method.tuple_combinations) for more
913 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
914 pub struct TupleCombinations
<I
, T
>
918 iter
: T
::Combination
,
923 pub trait HasCombination
<I
>: Sized
{
924 type Combination
: From
<I
> + Iterator
<Item
= Self>;
927 /// Create a new `TupleCombinations` from a clonable iterator.
928 pub fn tuple_combinations
<T
, I
>(iter
: I
) -> TupleCombinations
<I
, T
>
929 where I
: Iterator
+ Clone
,
931 T
: HasCombination
<I
>,
934 iter
: T
::Combination
::from(iter
),
940 impl<I
, T
> Iterator
for TupleCombinations
<I
, T
>
942 T
: HasCombination
<I
>,
946 fn next(&mut self) -> Option
<Self::Item
> {
952 pub struct Tuple1Combination
<I
> {
956 impl<I
> From
<I
> for Tuple1Combination
<I
> {
957 fn from(iter
: I
) -> Self {
958 Tuple1Combination { iter: iter }
962 impl<I
: Iterator
> Iterator
for Tuple1Combination
<I
> {
963 type Item
= (I
::Item
,);
965 fn next(&mut self) -> Option
<Self::Item
> {
966 self.iter
.next().map(|x
| (x
,))
970 impl<I
: Iterator
> HasCombination
<I
> for (I
::Item
,) {
971 type Combination
= Tuple1Combination
<I
>;
974 macro_rules
! impl_tuple_combination
{
975 ($C
:ident $P
:ident
; $A
:ident
, $
($I
:ident
),* ; $
($X
:ident
)*) => (
977 pub struct $C
<I
: Iterator
> {
978 item
: Option
<I
::Item
>,
983 impl<I
: Iterator
+ Clone
> From
<I
> for $C
<I
> {
984 fn from(mut iter
: I
) -> Self {
993 impl<I
: Iterator
+ Clone
> From
<I
> for $C
<Fuse
<I
>> {
994 fn from(iter
: I
) -> Self {
995 let mut iter
= iter
.fuse();
1004 impl<I
, $A
> Iterator
for $C
<I
>
1005 where I
: Iterator
<Item
= $A
> + Clone
,
1008 type Item
= ($
($I
),*);
1010 fn next(&mut self) -> Option
<Self::Item
> {
1011 if let Some(($
($X
),*,)) = self.c
.next() {
1012 let z
= self.item
.clone().unwrap();
1015 self.item
= self.iter
.next();
1016 self.item
.clone().and_then(|z
| {
1017 self.c
= $P
::from(self.iter
.clone());
1018 self.c
.next().map(|($
($X
),*,)| (z
, $
($X
),*))
1024 impl<I
, $A
> HasCombination
<I
> for ($
($I
),*)
1025 where I
: Iterator
<Item
= $A
> + Clone
,
1028 type Combination
= $C
<Fuse
<I
>>;
1033 impl_tuple_combination
!(Tuple2Combination Tuple1Combination
; A
, A
, A
; a
);
1034 impl_tuple_combination
!(Tuple3Combination Tuple2Combination
; A
, A
, A
, A
; a b
);
1035 impl_tuple_combination
!(Tuple4Combination Tuple3Combination
; A
, A
, A
, A
, A
; a b c
);
1038 /// An iterator adapter to simply flatten a structure.
1040 /// See [`.flatten()`](../trait.Itertools.html#method.flatten) for more information.
1041 #[derive(Clone, Debug)]
1042 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
1043 pub struct Flatten
<I
, J
> {
1048 /// Flatten an iterable of iterables into a single combined sequence of all
1049 /// the elements in the iterables.
1051 /// This is more or less equivalent to `.flat_map` with an identity
1054 /// This is an `IntoIterator`-enabled version of the [`.flatten()`][1] adaptor.
1056 /// [1]: trait.Itertools.html#method.flatten
1059 /// use itertools::flatten;
1061 /// let data = vec![vec![1, 2, 3], vec![4, 5, 6]];
1063 /// itertools::assert_equal(flatten(&data),
1064 /// &[1, 2, 3, 4, 5, 6]);
1066 pub fn flatten
<I
, J
>(iterable
: I
) -> Flatten
<I
::IntoIter
, J
>
1067 where I
: IntoIterator
,
1068 I
::Item
: IntoIterator
<IntoIter
=J
, Item
=J
::Item
>,
1072 iter
: iterable
.into_iter(),
1077 impl<I
, J
> Iterator
for Flatten
<I
, J
>
1079 I
::Item
: IntoIterator
<IntoIter
=J
, Item
=J
::Item
>,
1082 type Item
= J
::Item
;
1083 fn next(&mut self) -> Option
<Self::Item
> {
1085 if let Some(ref mut f
) = self.front
{
1087 elt @
Some(_
) => return elt
,
1091 if let Some(next_front
) = self.iter
.next() {
1092 self.front
= Some(next_front
.into_iter());
1100 // special case to convert segmented iterator into consecutive loops
1101 fn fold
<Acc
, G
>(self, init
: Acc
, mut f
: G
) -> Acc
1102 where G
: FnMut(Acc
, Self::Item
) -> Acc
,
1104 let mut accum
= init
;
1105 if let Some(iter
) = self.front
{
1106 accum
= fold(iter
, accum
, &mut f
);
1108 self.iter
.fold(accum
, move |accum
, iter
| fold(iter
, accum
, &mut f
))
1113 /// An iterator adapter to apply a transformation within a nested `Result`.
1115 /// See [`.map_results()`](../trait.Itertools.html#method.map_results) for more information.
1116 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
1117 pub struct MapResults
<I
, F
> {
1122 /// Create a new `MapResults` iterator.
1123 pub fn map_results
<I
, F
, T
, U
, E
>(iter
: I
, f
: F
) -> MapResults
<I
, F
>
1124 where I
: Iterator
<Item
= Result
<T
, E
>>,
1133 impl<I
, F
, T
, U
, E
> Iterator
for MapResults
<I
, F
>
1134 where I
: Iterator
<Item
= Result
<T
, E
>>,
1137 type Item
= Result
<U
, E
>;
1139 fn next(&mut self) -> Option
<Self::Item
> {
1140 self.iter
.next().map(|v
| v
.map(&mut self.f
))
1143 fn size_hint(&self) -> (usize, Option
<usize>) {
1144 self.iter
.size_hint()
1147 fn fold
<Acc
, Fold
>(self, init
: Acc
, mut fold_f
: Fold
) -> Acc
1148 where Fold
: FnMut(Acc
, Self::Item
) -> Acc
,
1151 self.iter
.fold(init
, move |acc
, v
| fold_f(acc
, v
.map(&mut f
)))
1154 fn collect
<C
>(self) -> C
1155 where C
: FromIterator
<Self::Item
>
1158 self.iter
.map(move |v
| v
.map(&mut f
)).collect()
1162 /// An iterator adapter to get the positions of each element that matches a predicate.
1164 /// See [`.positions()`](../trait.Itertools.html#method.positions) for more information.
1165 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
1166 pub struct Positions
<I
, F
> {
1172 /// Create a new `Positions` iterator.
1173 pub fn positions
<I
, F
>(iter
: I
, f
: F
) -> Positions
<I
, F
>
1175 F
: FnMut(I
::Item
) -> bool
,
1184 impl<I
, F
> Iterator
for Positions
<I
, F
>
1186 F
: FnMut(I
::Item
) -> bool
,
1190 fn next(&mut self) -> Option
<Self::Item
> {
1191 while let Some(v
) = self.iter
.next() {
1201 fn size_hint(&self) -> (usize, Option
<usize>) {
1202 (0, self.iter
.size_hint().1)
1206 impl<I
, F
> DoubleEndedIterator
for Positions
<I
, F
>
1207 where I
: DoubleEndedIterator
+ ExactSizeIterator
,
1208 F
: FnMut(I
::Item
) -> bool
,
1210 fn next_back(&mut self) -> Option
<Self::Item
> {
1211 while let Some(v
) = self.iter
.next_back() {
1213 return Some(self.count
+ self.iter
.len())
1220 /// An iterator adapter to apply a mutating function to each element before yielding it.
1222 /// See [`.update()`](../trait.Itertools.html#method.update) for more information.
1223 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
1224 pub struct Update
<I
, F
> {
1229 /// Create a new `Update` iterator.
1230 pub fn update
<I
, F
>(iter
: I
, f
: F
) -> Update
<I
, F
>
1233 F
: FnMut(&mut I
::Item
),
1235 Update { iter: iter, f: f }
1238 impl<I
, F
> Iterator
for Update
<I
, F
>
1241 F
: FnMut(&mut I
::Item
),
1243 type Item
= I
::Item
;
1245 fn next(&mut self) -> Option
<Self::Item
> {
1246 if let Some(mut v
) = self.iter
.next() {
1254 fn size_hint(&self) -> (usize, Option
<usize>) {
1255 self.iter
.size_hint()
1258 fn fold
<Acc
, G
>(self, init
: Acc
, mut g
: G
) -> Acc
1259 where G
: FnMut(Acc
, Self::Item
) -> Acc
,
1262 self.iter
.fold(init
, move |acc
, mut v
| { f(&mut v); g(acc, v) }
)
1265 // if possible, re-use inner iterator specializations in collect
1266 fn collect
<C
>(self) -> C
1267 where C
: FromIterator
<Self::Item
>
1270 self.iter
.map(move |mut v
| { f(&mut v); v }
).collect()
1274 impl<I
, F
> ExactSizeIterator
for Update
<I
, F
>
1276 I
: ExactSizeIterator
,
1277 F
: FnMut(&mut I
::Item
),
1280 impl<I
, F
> DoubleEndedIterator
for Update
<I
, F
>
1282 I
: DoubleEndedIterator
,
1283 F
: FnMut(&mut I
::Item
),
1285 fn next_back(&mut self) -> Option
<Self::Item
> {
1286 if let Some(mut v
) = self.iter
.next_back() {