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 #[cfg(feature = "use_alloc")]
18 use crate::Itertools;
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 running index.
39 ///
40 /// [`IntoIterator`] enabled version of [`Iterator::enumerate`].
41 ///
42 /// ```
43 /// use itertools::enumerate;
44 ///
45 /// for (i, elt) in enumerate(&[1, 2, 3]) {
46 ///     /* loop body */
47 /// }
48 /// ```
enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter> where I: IntoIterator49 pub fn enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter>
50     where I: IntoIterator
51 {
52     iterable.into_iter().enumerate()
53 }
54 
55 /// Iterate `iterable` in reverse.
56 ///
57 /// [`IntoIterator`] enabled version of [`Iterator::rev`].
58 ///
59 /// ```
60 /// use itertools::rev;
61 ///
62 /// for elt in rev(&[1, 2, 3]) {
63 ///     /* loop body */
64 /// }
65 /// ```
rev<I>(iterable: I) -> iter::Rev<I::IntoIter> where I: IntoIterator, I::IntoIter: DoubleEndedIterator66 pub fn rev<I>(iterable: I) -> iter::Rev<I::IntoIter>
67     where I: IntoIterator,
68           I::IntoIter: DoubleEndedIterator
69 {
70     iterable.into_iter().rev()
71 }
72 
73 /// Iterate `i` and `j` in lock step.
74 ///
75 /// [`IntoIterator`] enabled version of [`Iterator::zip`].
76 ///
77 /// ```
78 /// use itertools::zip;
79 ///
80 /// let data = [1, 2, 3, 4, 5];
81 /// for (a, b) in zip(&data, &data[1..]) {
82 ///     /* loop body */
83 /// }
84 /// ```
zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter> where I: IntoIterator, J: IntoIterator85 pub fn zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter>
86     where I: IntoIterator,
87           J: IntoIterator
88 {
89     i.into_iter().zip(j)
90 }
91 
92 /// Create an iterator that first iterates `i` and then `j`.
93 ///
94 /// [`IntoIterator`] enabled version of [`Iterator::chain`].
95 ///
96 /// ```
97 /// use itertools::chain;
98 ///
99 /// for elt in chain(&[1, 2, 3], &[4]) {
100 ///     /* loop body */
101 /// }
102 /// ```
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>103 pub fn chain<I, J>(i: I, j: J) -> iter::Chain<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
104     where I: IntoIterator,
105           J: IntoIterator<Item = I::Item>
106 {
107     i.into_iter().chain(j)
108 }
109 
110 /// Create an iterator that clones each element from &T to T
111 ///
112 /// [`IntoIterator`] enabled version of [`Iterator::cloned`].
113 ///
114 /// ```
115 /// use itertools::cloned;
116 ///
117 /// assert_eq!(cloned(b"abc").next(), Some(b'a'));
118 /// ```
cloned<'a, I, T: 'a>(iterable: I) -> iter::Cloned<I::IntoIter> where I: IntoIterator<Item=&'a T>, T: Clone,119 pub fn cloned<'a, I, T: 'a>(iterable: I) -> iter::Cloned<I::IntoIter>
120     where I: IntoIterator<Item=&'a T>,
121           T: Clone,
122 {
123     iterable.into_iter().cloned()
124 }
125 
126 /// Perform a fold operation over the iterable.
127 ///
128 /// [`IntoIterator`] enabled version of [`Iterator::fold`].
129 ///
130 /// ```
131 /// use itertools::fold;
132 ///
133 /// assert_eq!(fold(&[1., 2., 3.], 0., |a, &b| f32::max(a, b)), 3.);
134 /// ```
fold<I, B, F>(iterable: I, init: B, f: F) -> B where I: IntoIterator, F: FnMut(B, I::Item) -> B135 pub fn fold<I, B, F>(iterable: I, init: B, f: F) -> B
136     where I: IntoIterator,
137           F: FnMut(B, I::Item) -> B
138 {
139     iterable.into_iter().fold(init, f)
140 }
141 
142 /// Test whether the predicate holds for all elements in the iterable.
143 ///
144 /// [`IntoIterator`] enabled version of [`Iterator::all`].
145 ///
146 /// ```
147 /// use itertools::all;
148 ///
149 /// assert!(all(&[1, 2, 3], |elt| *elt > 0));
150 /// ```
all<I, F>(iterable: I, f: F) -> bool where I: IntoIterator, F: FnMut(I::Item) -> bool151 pub fn all<I, F>(iterable: I, f: F) -> bool
152     where I: IntoIterator,
153           F: FnMut(I::Item) -> bool
154 {
155     iterable.into_iter().all(f)
156 }
157 
158 /// Test whether the predicate holds for any elements in the iterable.
159 ///
160 /// [`IntoIterator`] enabled version of [`Iterator::any`].
161 ///
162 /// ```
163 /// use itertools::any;
164 ///
165 /// assert!(any(&[0, -1, 2], |elt| *elt > 0));
166 /// ```
any<I, F>(iterable: I, f: F) -> bool where I: IntoIterator, F: FnMut(I::Item) -> bool167 pub fn any<I, F>(iterable: I, f: F) -> bool
168     where I: IntoIterator,
169           F: FnMut(I::Item) -> bool
170 {
171     iterable.into_iter().any(f)
172 }
173 
174 /// Return the maximum value of the iterable.
175 ///
176 /// [`IntoIterator`] enabled version of [`Iterator::max`].
177 ///
178 /// ```
179 /// use itertools::max;
180 ///
181 /// assert_eq!(max(0..10), Some(9));
182 /// ```
max<I>(iterable: I) -> Option<I::Item> where I: IntoIterator, I::Item: Ord183 pub fn max<I>(iterable: I) -> Option<I::Item>
184     where I: IntoIterator,
185           I::Item: Ord
186 {
187     iterable.into_iter().max()
188 }
189 
190 /// Return the minimum value of the iterable.
191 ///
192 /// [`IntoIterator`] enabled version of [`Iterator::min`].
193 ///
194 /// ```
195 /// use itertools::min;
196 ///
197 /// assert_eq!(min(0..10), Some(0));
198 /// ```
min<I>(iterable: I) -> Option<I::Item> where I: IntoIterator, I::Item: Ord199 pub fn min<I>(iterable: I) -> Option<I::Item>
200     where I: IntoIterator,
201           I::Item: Ord
202 {
203     iterable.into_iter().min()
204 }
205 
206 
207 /// Combine all iterator elements into one String, seperated by `sep`.
208 ///
209 /// [`IntoIterator`] enabled version of [`Itertools::join`].
210 ///
211 /// ```
212 /// use itertools::join;
213 ///
214 /// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
215 /// ```
216 #[cfg(feature = "use_alloc")]
join<I>(iterable: I, sep: &str) -> String where I: IntoIterator, I::Item: Display217 pub fn join<I>(iterable: I, sep: &str) -> String
218     where I: IntoIterator,
219           I::Item: Display
220 {
221     iterable.into_iter().join(sep)
222 }
223 
224 /// Sort all iterator elements into a new iterator in ascending order.
225 ///
226 /// [`IntoIterator`] enabled version of [`Itertools::sorted`].
227 ///
228 /// ```
229 /// use itertools::sorted;
230 /// use itertools::assert_equal;
231 ///
232 /// assert_equal(sorted("rust".chars()), "rstu".chars());
233 /// ```
234 #[cfg(feature = "use_alloc")]
sorted<I>(iterable: I) -> VecIntoIter<I::Item> where I: IntoIterator, I::Item: Ord235 pub fn sorted<I>(iterable: I) -> VecIntoIter<I::Item>
236     where I: IntoIterator,
237           I::Item: Ord
238 {
239     iterable.into_iter().sorted()
240 }
241 
242