blob: 6674030405276bf3836047ca4566264c047e6159 [file] [log] [blame]
Jakub Kotura425e552020-12-21 17:28:15 +01001//! Free functions that create iterator adaptors or call iterator methods.
2//!
Joel Galensonb593e252021-06-21 13:15:57 -07003//! The benefit of free functions is that they accept any [`IntoIterator`] as
Jakub Kotura425e552020-12-21 17:28:15 +01004//! argument, so the resulting code may be easier to read.
5
Joel Galenson6f798712021-04-01 17:03:06 -07006#[cfg(feature = "use_alloc")]
Jakub Kotura425e552020-12-21 17:28:15 +01007use std::fmt::Display;
8use std::iter::{self, Zip};
Joel Galenson6f798712021-04-01 17:03:06 -07009#[cfg(feature = "use_alloc")]
10type VecIntoIter<T> = alloc::vec::IntoIter<T>;
Jakub Kotura425e552020-12-21 17:28:15 +010011
Joel Galenson6f798712021-04-01 17:03:06 -070012#[cfg(feature = "use_alloc")]
13use alloc::{
14 string::String,
15};
16
Jakub Kotura425e552020-12-21 17:28:15 +010017use crate::Itertools;
David LeGareb72e9052022-03-02 16:21:08 +000018use crate::intersperse::{Intersperse, IntersperseWith};
Jakub Kotura425e552020-12-21 17:28:15 +010019
20pub use crate::adaptors::{
21 interleave,
22 merge,
23 put_back,
24};
Joel Galenson6f798712021-04-01 17:03:06 -070025#[cfg(feature = "use_alloc")]
Jakub Kotura425e552020-12-21 17:28:15 +010026pub use crate::put_back_n_impl::put_back_n;
Joel Galenson6f798712021-04-01 17:03:06 -070027#[cfg(feature = "use_alloc")]
Jakub Kotura425e552020-12-21 17:28:15 +010028pub use crate::multipeek_impl::multipeek;
Joel Galenson6f798712021-04-01 17:03:06 -070029#[cfg(feature = "use_alloc")]
30pub use crate::peek_nth::peek_nth;
31#[cfg(feature = "use_alloc")]
Jakub Kotura425e552020-12-21 17:28:15 +010032pub use crate::kmerge_impl::kmerge;
33pub use crate::zip_eq_impl::zip_eq;
34pub use crate::merge_join::merge_join_by;
Joel Galenson6f798712021-04-01 17:03:06 -070035#[cfg(feature = "use_alloc")]
Jakub Kotura425e552020-12-21 17:28:15 +010036pub use crate::rciter_impl::rciter;
37
David LeGareb72e9052022-03-02 16:21:08 +000038/// Iterate `iterable` with a particular value inserted between each element.
39///
40/// [`IntoIterator`] enabled version of [`Iterator::intersperse`].
41///
42/// ```
43/// use itertools::intersperse;
44///
45/// itertools::assert_equal(intersperse((0..3), 8), vec![0, 8, 1, 8, 2]);
46/// ```
47pub fn intersperse<I>(iterable: I, element: I::Item) -> Intersperse<I::IntoIter>
48 where I: IntoIterator,
49 <I as IntoIterator>::Item: Clone
50{
51 Itertools::intersperse(iterable.into_iter(), element)
52}
53
54/// Iterate `iterable` with a particular value created by a function inserted
55/// between each element.
56///
57/// [`IntoIterator`] enabled version of [`Iterator::intersperse_with`].
58///
59/// ```
60/// use itertools::intersperse_with;
61///
62/// let mut i = 10;
63/// itertools::assert_equal(intersperse_with((0..3), || { i -= 1; i }), vec![0, 9, 1, 8, 2]);
64/// assert_eq!(i, 8);
65/// ```
66pub fn intersperse_with<I, F>(iterable: I, element: F) -> IntersperseWith<I::IntoIter, F>
67 where I: IntoIterator,
68 F: FnMut() -> I::Item
69{
70 Itertools::intersperse_with(iterable.into_iter(), element)
71}
72
Jakub Kotura425e552020-12-21 17:28:15 +010073/// Iterate `iterable` with a running index.
74///
Joel Galensonb593e252021-06-21 13:15:57 -070075/// [`IntoIterator`] enabled version of [`Iterator::enumerate`].
Jakub Kotura425e552020-12-21 17:28:15 +010076///
77/// ```
78/// use itertools::enumerate;
79///
80/// for (i, elt) in enumerate(&[1, 2, 3]) {
81/// /* loop body */
82/// }
83/// ```
84pub fn enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter>
85 where I: IntoIterator
86{
87 iterable.into_iter().enumerate()
88}
89
90/// Iterate `iterable` in reverse.
91///
Joel Galensonb593e252021-06-21 13:15:57 -070092/// [`IntoIterator`] enabled version of [`Iterator::rev`].
Jakub Kotura425e552020-12-21 17:28:15 +010093///
94/// ```
95/// use itertools::rev;
96///
97/// for elt in rev(&[1, 2, 3]) {
98/// /* loop body */
99/// }
100/// ```
101pub fn rev<I>(iterable: I) -> iter::Rev<I::IntoIter>
102 where I: IntoIterator,
103 I::IntoIter: DoubleEndedIterator
104{
105 iterable.into_iter().rev()
106}
107
108/// Iterate `i` and `j` in lock step.
109///
Joel Galensonb593e252021-06-21 13:15:57 -0700110/// [`IntoIterator`] enabled version of [`Iterator::zip`].
Jakub Kotura425e552020-12-21 17:28:15 +0100111///
112/// ```
113/// use itertools::zip;
114///
115/// let data = [1, 2, 3, 4, 5];
116/// for (a, b) in zip(&data, &data[1..]) {
117/// /* loop body */
118/// }
119/// ```
120pub fn zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter>
121 where I: IntoIterator,
122 J: IntoIterator
123{
124 i.into_iter().zip(j)
125}
126
127/// Create an iterator that first iterates `i` and then `j`.
128///
Joel Galensonb593e252021-06-21 13:15:57 -0700129/// [`IntoIterator`] enabled version of [`Iterator::chain`].
Jakub Kotura425e552020-12-21 17:28:15 +0100130///
131/// ```
132/// use itertools::chain;
133///
134/// for elt in chain(&[1, 2, 3], &[4]) {
135/// /* loop body */
136/// }
137/// ```
138pub fn chain<I, J>(i: I, j: J) -> iter::Chain<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
139 where I: IntoIterator,
140 J: IntoIterator<Item = I::Item>
141{
142 i.into_iter().chain(j)
143}
144
145/// Create an iterator that clones each element from &T to T
146///
Joel Galensonb593e252021-06-21 13:15:57 -0700147/// [`IntoIterator`] enabled version of [`Iterator::cloned`].
Jakub Kotura425e552020-12-21 17:28:15 +0100148///
149/// ```
150/// use itertools::cloned;
151///
152/// assert_eq!(cloned(b"abc").next(), Some(b'a'));
153/// ```
154pub fn cloned<'a, I, T: 'a>(iterable: I) -> iter::Cloned<I::IntoIter>
155 where I: IntoIterator<Item=&'a T>,
156 T: Clone,
157{
158 iterable.into_iter().cloned()
159}
160
161/// Perform a fold operation over the iterable.
162///
Joel Galensonb593e252021-06-21 13:15:57 -0700163/// [`IntoIterator`] enabled version of [`Iterator::fold`].
Jakub Kotura425e552020-12-21 17:28:15 +0100164///
165/// ```
166/// use itertools::fold;
167///
168/// assert_eq!(fold(&[1., 2., 3.], 0., |a, &b| f32::max(a, b)), 3.);
169/// ```
170pub fn fold<I, B, F>(iterable: I, init: B, f: F) -> B
171 where I: IntoIterator,
172 F: FnMut(B, I::Item) -> B
173{
174 iterable.into_iter().fold(init, f)
175}
176
177/// Test whether the predicate holds for all elements in the iterable.
178///
Joel Galensonb593e252021-06-21 13:15:57 -0700179/// [`IntoIterator`] enabled version of [`Iterator::all`].
Jakub Kotura425e552020-12-21 17:28:15 +0100180///
181/// ```
182/// use itertools::all;
183///
184/// assert!(all(&[1, 2, 3], |elt| *elt > 0));
185/// ```
186pub fn all<I, F>(iterable: I, f: F) -> bool
187 where I: IntoIterator,
188 F: FnMut(I::Item) -> bool
189{
190 iterable.into_iter().all(f)
191}
192
193/// Test whether the predicate holds for any elements in the iterable.
194///
Joel Galensonb593e252021-06-21 13:15:57 -0700195/// [`IntoIterator`] enabled version of [`Iterator::any`].
Jakub Kotura425e552020-12-21 17:28:15 +0100196///
197/// ```
198/// use itertools::any;
199///
200/// assert!(any(&[0, -1, 2], |elt| *elt > 0));
201/// ```
202pub fn any<I, F>(iterable: I, f: F) -> bool
203 where I: IntoIterator,
204 F: FnMut(I::Item) -> bool
205{
206 iterable.into_iter().any(f)
207}
208
209/// Return the maximum value of the iterable.
210///
Joel Galensonb593e252021-06-21 13:15:57 -0700211/// [`IntoIterator`] enabled version of [`Iterator::max`].
Jakub Kotura425e552020-12-21 17:28:15 +0100212///
213/// ```
214/// use itertools::max;
215///
216/// assert_eq!(max(0..10), Some(9));
217/// ```
218pub fn max<I>(iterable: I) -> Option<I::Item>
219 where I: IntoIterator,
220 I::Item: Ord
221{
222 iterable.into_iter().max()
223}
224
225/// Return the minimum value of the iterable.
226///
Joel Galensonb593e252021-06-21 13:15:57 -0700227/// [`IntoIterator`] enabled version of [`Iterator::min`].
Jakub Kotura425e552020-12-21 17:28:15 +0100228///
229/// ```
230/// use itertools::min;
231///
232/// assert_eq!(min(0..10), Some(0));
233/// ```
234pub fn min<I>(iterable: I) -> Option<I::Item>
235 where I: IntoIterator,
236 I::Item: Ord
237{
238 iterable.into_iter().min()
239}
240
241
242/// Combine all iterator elements into one String, seperated by `sep`.
243///
Joel Galensonb593e252021-06-21 13:15:57 -0700244/// [`IntoIterator`] enabled version of [`Itertools::join`].
Jakub Kotura425e552020-12-21 17:28:15 +0100245///
246/// ```
247/// use itertools::join;
248///
249/// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
250/// ```
Joel Galenson6f798712021-04-01 17:03:06 -0700251#[cfg(feature = "use_alloc")]
Jakub Kotura425e552020-12-21 17:28:15 +0100252pub fn join<I>(iterable: I, sep: &str) -> String
253 where I: IntoIterator,
254 I::Item: Display
255{
256 iterable.into_iter().join(sep)
257}
258
259/// Sort all iterator elements into a new iterator in ascending order.
260///
Joel Galensonb593e252021-06-21 13:15:57 -0700261/// [`IntoIterator`] enabled version of [`Itertools::sorted`].
Jakub Kotura425e552020-12-21 17:28:15 +0100262///
263/// ```
264/// use itertools::sorted;
265/// use itertools::assert_equal;
266///
267/// assert_equal(sorted("rust".chars()), "rstu".chars());
268/// ```
Joel Galenson6f798712021-04-01 17:03:06 -0700269#[cfg(feature = "use_alloc")]
Jakub Kotura425e552020-12-21 17:28:15 +0100270pub fn sorted<I>(iterable: I) -> VecIntoIter<I::Item>
271 where I: IntoIterator,
272 I::Item: Ord
273{
274 iterable.into_iter().sorted()
275}
276