1 //! Free functions that create iterator adaptors or call iterator methods.
2 //!
3 //! The benefit of free functions is that they accept any [`IntoIterator`] as
4 //! argument, so the resulting code may be easier to read.
5 
6 #[cfg(feature = "use_alloc")]
7 use std::fmt::Display;
8 use std::iter::{self, Zip};
9 #[cfg(feature = "use_alloc")]
10 type VecIntoIter<T> = alloc::vec::IntoIter<T>;
11 
12 #[cfg(feature = "use_alloc")]
13 use alloc::{
14     string::String,
15 };
16 
17 use crate::Itertools;
18 use crate::intersperse::{Intersperse, IntersperseWith};
19 
20 pub use crate::adaptors::{
21     interleave,
22     merge,
23     put_back,
24 };
25 #[cfg(feature = "use_alloc")]
26 pub use crate::put_back_n_impl::put_back_n;
27 #[cfg(feature = "use_alloc")]
28 pub use crate::multipeek_impl::multipeek;
29 #[cfg(feature = "use_alloc")]
30 pub use crate::peek_nth::peek_nth;
31 #[cfg(feature = "use_alloc")]
32 pub use crate::kmerge_impl::kmerge;
33 pub use crate::zip_eq_impl::zip_eq;
34 pub use crate::merge_join::merge_join_by;
35 #[cfg(feature = "use_alloc")]
36 pub use crate::rciter_impl::rciter;
37 
38 /// 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 /// ```
intersperse<I>(iterable: I, element: I::Item) -> Intersperse<I::IntoIter> where I: IntoIterator, <I as IntoIterator>::Item: Clone47 pub 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 /// ```
intersperse_with<I, F>(iterable: I, element: F) -> IntersperseWith<I::IntoIter, F> where I: IntoIterator, F: FnMut() -> I::Item66 pub 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 
73 /// Iterate `iterable` with a running index.
74 ///
75 /// [`IntoIterator`] enabled version of [`Iterator::enumerate`].
76 ///
77 /// ```
78 /// use itertools::enumerate;
79 ///
80 /// for (i, elt) in enumerate(&[1, 2, 3]) {
81 ///     /* loop body */
82 /// }
83 /// ```
enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter> where I: IntoIterator84 pub 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 ///
92 /// [`IntoIterator`] enabled version of [`Iterator::rev`].
93 ///
94 /// ```
95 /// use itertools::rev;
96 ///
97 /// for elt in rev(&[1, 2, 3]) {
98 ///     /* loop body */
99 /// }
100 /// ```
rev<I>(iterable: I) -> iter::Rev<I::IntoIter> where I: IntoIterator, I::IntoIter: DoubleEndedIterator101 pub 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 ///
110 /// [`IntoIterator`] enabled version of [`Iterator::zip`].
111 ///
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 /// ```
zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter> where I: IntoIterator, J: IntoIterator120 pub 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 ///
129 /// [`IntoIterator`] enabled version of [`Iterator::chain`].
130 ///
131 /// ```
132 /// use itertools::chain;
133 ///
134 /// for elt in chain(&[1, 2, 3], &[4]) {
135 ///     /* loop body */
136 /// }
137 /// ```
chain<I, J>(i: I, j: J) -> iter::Chain<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter> where I: IntoIterator, J: IntoIterator<Item = I::Item>138 pub 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 ///
147 /// [`IntoIterator`] enabled version of [`Iterator::cloned`].
148 ///
149 /// ```
150 /// use itertools::cloned;
151 ///
152 /// assert_eq!(cloned(b"abc").next(), Some(b'a'));
153 /// ```
cloned<'a, I, T: 'a>(iterable: I) -> iter::Cloned<I::IntoIter> where I: IntoIterator<Item=&'a T>, T: Clone,154 pub 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 ///
163 /// [`IntoIterator`] enabled version of [`Iterator::fold`].
164 ///
165 /// ```
166 /// use itertools::fold;
167 ///
168 /// assert_eq!(fold(&[1., 2., 3.], 0., |a, &b| f32::max(a, b)), 3.);
169 /// ```
fold<I, B, F>(iterable: I, init: B, f: F) -> B where I: IntoIterator, F: FnMut(B, I::Item) -> B170 pub 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 ///
179 /// [`IntoIterator`] enabled version of [`Iterator::all`].
180 ///
181 /// ```
182 /// use itertools::all;
183 ///
184 /// assert!(all(&[1, 2, 3], |elt| *elt > 0));
185 /// ```
all<I, F>(iterable: I, f: F) -> bool where I: IntoIterator, F: FnMut(I::Item) -> bool186 pub 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 ///
195 /// [`IntoIterator`] enabled version of [`Iterator::any`].
196 ///
197 /// ```
198 /// use itertools::any;
199 ///
200 /// assert!(any(&[0, -1, 2], |elt| *elt > 0));
201 /// ```
any<I, F>(iterable: I, f: F) -> bool where I: IntoIterator, F: FnMut(I::Item) -> bool202 pub 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 ///
211 /// [`IntoIterator`] enabled version of [`Iterator::max`].
212 ///
213 /// ```
214 /// use itertools::max;
215 ///
216 /// assert_eq!(max(0..10), Some(9));
217 /// ```
max<I>(iterable: I) -> Option<I::Item> where I: IntoIterator, I::Item: Ord218 pub 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 ///
227 /// [`IntoIterator`] enabled version of [`Iterator::min`].
228 ///
229 /// ```
230 /// use itertools::min;
231 ///
232 /// assert_eq!(min(0..10), Some(0));
233 /// ```
min<I>(iterable: I) -> Option<I::Item> where I: IntoIterator, I::Item: Ord234 pub 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 ///
244 /// [`IntoIterator`] enabled version of [`Itertools::join`].
245 ///
246 /// ```
247 /// use itertools::join;
248 ///
249 /// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
250 /// ```
251 #[cfg(feature = "use_alloc")]
join<I>(iterable: I, sep: &str) -> String where I: IntoIterator, I::Item: Display252 pub 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 ///
261 /// [`IntoIterator`] enabled version of [`Itertools::sorted`].
262 ///
263 /// ```
264 /// use itertools::sorted;
265 /// use itertools::assert_equal;
266 ///
267 /// assert_equal(sorted("rust".chars()), "rstu".chars());
268 /// ```
269 #[cfg(feature = "use_alloc")]
sorted<I>(iterable: I) -> VecIntoIter<I::Item> where I: IntoIterator, I::Item: Ord270 pub fn sorted<I>(iterable: I) -> VecIntoIter<I::Item>
271     where I: IntoIterator,
272           I::Item: Ord
273 {
274     iterable.into_iter().sorted()
275 }
276 
277