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 /// Converts the arguments to iterators and zips them.
109 ///
110 /// [`IntoIterator`] enabled version of [`Iterator::zip`].
111 ///
112 /// ## Example
113 ///
114 /// ```
115 /// use itertools::zip;
116 ///
117 /// let mut result: Vec<(i32, char)> = Vec::new();
118 ///
119 /// for (a, b) in zip(&[1, 2, 3, 4, 5], &['a', 'b', 'c']) {
120 /// result.push((*a, *b));
121 /// }
122 /// assert_eq!(result, vec![(1, 'a'),(2, 'b'),(3, 'c')]);
123 /// ```
124 #[deprecated(note="Use [std::iter::zip](https://doc.rust-lang.org/std/iter/fn.zip.html) instead", since="0.10.4")]
zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter> where I: IntoIterator, J: IntoIterator125 pub fn zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter>
126 where I: IntoIterator,
127 J: IntoIterator
128 {
129 i.into_iter().zip(j)
130 }
131
132
133 /// Takes two iterables and creates a new iterator over both in sequence.
134 ///
135 /// [`IntoIterator`] enabled version of [`Iterator::chain`].
136 ///
137 /// ## Example
138 /// ```
139 /// use itertools::chain;
140 ///
141 /// let mut result:Vec<i32> = Vec::new();
142 ///
143 /// for element in chain(&[1, 2, 3], &[4]) {
144 /// result.push(*element);
145 /// }
146 /// assert_eq!(result, vec![1, 2, 3, 4]);
147 /// ```
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>148 pub fn chain<I, J>(i: I, j: J) -> iter::Chain<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
149 where I: IntoIterator,
150 J: IntoIterator<Item = I::Item>
151 {
152 i.into_iter().chain(j)
153 }
154
155 /// Create an iterator that clones each element from &T to T
156 ///
157 /// [`IntoIterator`] enabled version of [`Iterator::cloned`].
158 ///
159 /// ```
160 /// use itertools::cloned;
161 ///
162 /// assert_eq!(cloned(b"abc").next(), Some(b'a'));
163 /// ```
cloned<'a, I, T: 'a>(iterable: I) -> iter::Cloned<I::IntoIter> where I: IntoIterator<Item=&'a T>, T: Clone,164 pub fn cloned<'a, I, T: 'a>(iterable: I) -> iter::Cloned<I::IntoIter>
165 where I: IntoIterator<Item=&'a T>,
166 T: Clone,
167 {
168 iterable.into_iter().cloned()
169 }
170
171 /// Perform a fold operation over the iterable.
172 ///
173 /// [`IntoIterator`] enabled version of [`Iterator::fold`].
174 ///
175 /// ```
176 /// use itertools::fold;
177 ///
178 /// assert_eq!(fold(&[1., 2., 3.], 0., |a, &b| f32::max(a, b)), 3.);
179 /// ```
fold<I, B, F>(iterable: I, init: B, f: F) -> B where I: IntoIterator, F: FnMut(B, I::Item) -> B180 pub fn fold<I, B, F>(iterable: I, init: B, f: F) -> B
181 where I: IntoIterator,
182 F: FnMut(B, I::Item) -> B
183 {
184 iterable.into_iter().fold(init, f)
185 }
186
187 /// Test whether the predicate holds for all elements in the iterable.
188 ///
189 /// [`IntoIterator`] enabled version of [`Iterator::all`].
190 ///
191 /// ```
192 /// use itertools::all;
193 ///
194 /// assert!(all(&[1, 2, 3], |elt| *elt > 0));
195 /// ```
all<I, F>(iterable: I, f: F) -> bool where I: IntoIterator, F: FnMut(I::Item) -> bool196 pub fn all<I, F>(iterable: I, f: F) -> bool
197 where I: IntoIterator,
198 F: FnMut(I::Item) -> bool
199 {
200 iterable.into_iter().all(f)
201 }
202
203 /// Test whether the predicate holds for any elements in the iterable.
204 ///
205 /// [`IntoIterator`] enabled version of [`Iterator::any`].
206 ///
207 /// ```
208 /// use itertools::any;
209 ///
210 /// assert!(any(&[0, -1, 2], |elt| *elt > 0));
211 /// ```
any<I, F>(iterable: I, f: F) -> bool where I: IntoIterator, F: FnMut(I::Item) -> bool212 pub fn any<I, F>(iterable: I, f: F) -> bool
213 where I: IntoIterator,
214 F: FnMut(I::Item) -> bool
215 {
216 iterable.into_iter().any(f)
217 }
218
219 /// Return the maximum value of the iterable.
220 ///
221 /// [`IntoIterator`] enabled version of [`Iterator::max`].
222 ///
223 /// ```
224 /// use itertools::max;
225 ///
226 /// assert_eq!(max(0..10), Some(9));
227 /// ```
max<I>(iterable: I) -> Option<I::Item> where I: IntoIterator, I::Item: Ord228 pub fn max<I>(iterable: I) -> Option<I::Item>
229 where I: IntoIterator,
230 I::Item: Ord
231 {
232 iterable.into_iter().max()
233 }
234
235 /// Return the minimum value of the iterable.
236 ///
237 /// [`IntoIterator`] enabled version of [`Iterator::min`].
238 ///
239 /// ```
240 /// use itertools::min;
241 ///
242 /// assert_eq!(min(0..10), Some(0));
243 /// ```
min<I>(iterable: I) -> Option<I::Item> where I: IntoIterator, I::Item: Ord244 pub fn min<I>(iterable: I) -> Option<I::Item>
245 where I: IntoIterator,
246 I::Item: Ord
247 {
248 iterable.into_iter().min()
249 }
250
251
252 /// Combine all iterator elements into one String, separated by `sep`.
253 ///
254 /// [`IntoIterator`] enabled version of [`Itertools::join`].
255 ///
256 /// ```
257 /// use itertools::join;
258 ///
259 /// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
260 /// ```
261 #[cfg(feature = "use_alloc")]
join<I>(iterable: I, sep: &str) -> String where I: IntoIterator, I::Item: Display262 pub fn join<I>(iterable: I, sep: &str) -> String
263 where I: IntoIterator,
264 I::Item: Display
265 {
266 iterable.into_iter().join(sep)
267 }
268
269 /// Sort all iterator elements into a new iterator in ascending order.
270 ///
271 /// [`IntoIterator`] enabled version of [`Itertools::sorted`].
272 ///
273 /// ```
274 /// use itertools::sorted;
275 /// use itertools::assert_equal;
276 ///
277 /// assert_equal(sorted("rust".chars()), "rstu".chars());
278 /// ```
279 #[cfg(feature = "use_alloc")]
sorted<I>(iterable: I) -> VecIntoIter<I::Item> where I: IntoIterator, I::Item: Ord280 pub fn sorted<I>(iterable: I) -> VecIntoIter<I::Item>
281 where I: IntoIterator,
282 I::Item: Ord
283 {
284 iterable.into_iter().sorted()
285 }
286
287