@@ -97,6 +97,8 @@ pub mod structs {
9797 TakeWhileRef , TupleCombinations , Update , WhileSome ,
9898 } ;
9999 #[ cfg( feature = "use_alloc" ) ]
100+ pub use crate :: array_chunks:: ArrayChunks ;
101+ #[ cfg( feature = "use_alloc" ) ]
100102 pub use crate :: combinations:: { ArrayCombinations , Combinations } ;
101103 #[ cfg( feature = "use_alloc" ) ]
102104 pub use crate :: combinations_with_replacement:: CombinationsWithReplacement ;
@@ -171,6 +173,8 @@ pub use crate::unziptuple::{multiunzip, MultiUnzip};
171173pub use crate :: with_position:: Position ;
172174pub use crate :: ziptuple:: multizip;
173175mod adaptors;
176+ #[ cfg( feature = "use_alloc" ) ]
177+ mod array_chunks;
174178mod either_or_both;
175179pub use crate :: either_or_both:: EitherOrBoth ;
176180#[ doc( hidden) ]
@@ -741,6 +745,57 @@ pub trait Itertools: Iterator {
741745 groupbylazy:: new_chunks ( self , size)
742746 }
743747
748+ /// Return an iterator that groups the items in arrays of const generic size `N`.
749+ ///
750+ /// Use the method `.remainder()` to access leftover items in case
751+ /// the number of items yielded by the original iterator is not a multiple of `N`.
752+ ///
753+ /// If `N` is 0, the resulting iterator will be equivalent to `repeat([])`, i.e.
754+ /// `next()` will always return `Some([])`.
755+ ///
756+ /// See also the method [`.next_array()`](Itertools::next_array).
757+ ///
758+ /// ```
759+ /// use itertools::Itertools;
760+ /// let mut v = Vec::new();
761+ /// for [a, b] in (1..5).array_chunks() {
762+ /// v.push([a, b]);
763+ /// }
764+ /// assert_eq!(v, vec![[1, 2], [3, 4]]);
765+ ///
766+ /// let mut it = (1..9).array_chunks();
767+ /// assert_eq!(Some([1, 2, 3]), it.next());
768+ /// assert_eq!(Some([4, 5, 6]), it.next());
769+ /// assert_eq!(None, it.next());
770+ /// itertools::assert_equal(it.remainder(), [7,8]);
771+ ///
772+ /// // this requires a type hint
773+ /// let it = (1..7).array_chunks::<3>();
774+ /// itertools::assert_equal(it, vec![[1, 2, 3], [4, 5, 6]]);
775+ ///
776+ /// // you can also specify the complete type
777+ /// use itertools::ArrayChunks;
778+ /// use std::ops::Range;
779+ ///
780+ /// let it: ArrayChunks<Range<u32>, 3> = (1..7).array_chunks();
781+ /// itertools::assert_equal(it, vec![[1, 2, 3], [4, 5, 6]]);
782+ ///
783+ /// let mut it = (1..3).array_chunks::<0>();
784+ /// assert_eq!(it.next(), Some([]));
785+ /// assert_eq!(it.next(), Some([]));
786+ /// // and so on for any further calls to `it.next()`
787+ /// itertools::assert_equal(it.remainder(), 1..3);
788+ /// ```
789+ ///
790+ /// See also [`Tuples::into_buffer`].
791+ #[ cfg( feature = "use_alloc" ) ]
792+ fn array_chunks < const N : usize > ( self ) -> ArrayChunks < Self , N >
793+ where
794+ Self : Sized ,
795+ {
796+ ArrayChunks :: new ( self )
797+ }
798+
744799 /// Return an iterator over all contiguous windows producing tuples of
745800 /// a specific size (up to 12).
746801 ///
0 commit comments