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_std")]
7 use std::fmt::Display;
8 use std::iter::{self, Zip};
9 #[cfg(feature = "use_std")]
10 type VecIntoIter<T> = ::std::vec::IntoIter<T>;
11 
12 #[cfg(feature = "use_std")]
13 use Itertools;
14 
15 pub use adaptors::{
16     interleave,
17     merge,
18     put_back,
19 };
20 #[cfg(feature = "use_std")]
21 pub use put_back_n_impl::put_back_n;
22 #[cfg(feature = "use_std")]
23 pub use multipeek_impl::multipeek;
24 #[cfg(feature = "use_std")]
25 pub use kmerge_impl::kmerge;
26 pub use zip_eq_impl::zip_eq;
27 pub use merge_join::merge_join_by;
28 #[cfg(feature = "use_std")]
29 pub use rciter_impl::rciter;
30 
31 /// Iterate `iterable` with a running index.
32 ///
33 /// `IntoIterator` enabled version of `.enumerate()`.
34 ///
35 /// ```
36 /// use itertools::enumerate;
37 ///
38 /// for (i, elt) in enumerate(&[1, 2, 3]) {
39 ///     /* loop body */
40 /// }
41 /// ```
enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter> where I: IntoIterator42 pub fn enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter>
43     where I: IntoIterator
44 {
45     iterable.into_iter().enumerate()
46 }
47 
48 /// Iterate `iterable` in reverse.
49 ///
50 /// `IntoIterator` enabled version of `.rev()`.
51 ///
52 /// ```
53 /// use itertools::rev;
54 ///
55 /// for elt in rev(&[1, 2, 3]) {
56 ///     /* loop body */
57 /// }
58 /// ```
rev<I>(iterable: I) -> iter::Rev<I::IntoIter> where I: IntoIterator, I::IntoIter: DoubleEndedIterator59 pub fn rev<I>(iterable: I) -> iter::Rev<I::IntoIter>
60     where I: IntoIterator,
61           I::IntoIter: DoubleEndedIterator
62 {
63     iterable.into_iter().rev()
64 }
65 
66 /// Iterate `i` and `j` in lock step.
67 ///
68 /// `IntoIterator` enabled version of `i.zip(j)`.
69 ///
70 /// ```
71 /// use itertools::zip;
72 ///
73 /// let data = [1, 2, 3, 4, 5];
74 /// for (a, b) in zip(&data, &data[1..]) {
75 ///     /* loop body */
76 /// }
77 /// ```
zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter> where I: IntoIterator, J: IntoIterator78 pub fn zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter>
79     where I: IntoIterator,
80           J: IntoIterator
81 {
82     i.into_iter().zip(j)
83 }
84 
85 /// Create an iterator that first iterates `i` and then `j`.
86 ///
87 /// `IntoIterator` enabled version of `i.chain(j)`.
88 ///
89 /// ```
90 /// use itertools::chain;
91 ///
92 /// for elt in chain(&[1, 2, 3], &[4]) {
93 ///     /* loop body */
94 /// }
95 /// ```
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>96 pub fn chain<I, J>(i: I, j: J) -> iter::Chain<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
97     where I: IntoIterator,
98           J: IntoIterator<Item = I::Item>
99 {
100     i.into_iter().chain(j)
101 }
102 
103 /// Create an iterator that clones each element from &T to T
104 ///
105 /// `IntoIterator` enabled version of `i.cloned()`.
106 ///
107 /// ```
108 /// use itertools::cloned;
109 ///
110 /// assert_eq!(cloned(b"abc").next(), Some(b'a'));
111 /// ```
cloned<'a, I, T: 'a>(iterable: I) -> iter::Cloned<I::IntoIter> where I: IntoIterator<Item=&'a T>, T: Clone,112 pub fn cloned<'a, I, T: 'a>(iterable: I) -> iter::Cloned<I::IntoIter>
113     where I: IntoIterator<Item=&'a T>,
114           T: Clone,
115 {
116     iterable.into_iter().cloned()
117 }
118 
119 /// Perform a fold operation over the iterable.
120 ///
121 /// `IntoIterator` enabled version of `i.fold(init, f)`
122 ///
123 /// ```
124 /// use itertools::fold;
125 ///
126 /// assert_eq!(fold(&[1., 2., 3.], 0., |a, &b| f32::max(a, b)), 3.);
127 /// ```
fold<I, B, F>(iterable: I, init: B, f: F) -> B where I: IntoIterator, F: FnMut(B, I::Item) -> B128 pub fn fold<I, B, F>(iterable: I, init: B, f: F) -> B
129     where I: IntoIterator,
130           F: FnMut(B, I::Item) -> B
131 {
132     iterable.into_iter().fold(init, f)
133 }
134 
135 /// Test whether the predicate holds for all elements in the iterable.
136 ///
137 /// `IntoIterator` enabled version of `i.all(f)`
138 ///
139 /// ```
140 /// use itertools::all;
141 ///
142 /// assert!(all(&[1, 2, 3], |elt| *elt > 0));
143 /// ```
all<I, F>(iterable: I, f: F) -> bool where I: IntoIterator, F: FnMut(I::Item) -> bool144 pub fn all<I, F>(iterable: I, f: F) -> bool
145     where I: IntoIterator,
146           F: FnMut(I::Item) -> bool
147 {
148     iterable.into_iter().all(f)
149 }
150 
151 /// Test whether the predicate holds for any elements in the iterable.
152 ///
153 /// `IntoIterator` enabled version of `i.any(f)`
154 ///
155 /// ```
156 /// use itertools::any;
157 ///
158 /// assert!(any(&[0, -1, 2], |elt| *elt > 0));
159 /// ```
any<I, F>(iterable: I, f: F) -> bool where I: IntoIterator, F: FnMut(I::Item) -> bool160 pub fn any<I, F>(iterable: I, f: F) -> bool
161     where I: IntoIterator,
162           F: FnMut(I::Item) -> bool
163 {
164     iterable.into_iter().any(f)
165 }
166 
167 /// Return the maximum value of the iterable.
168 ///
169 /// `IntoIterator` enabled version of `i.max()`.
170 ///
171 /// ```
172 /// use itertools::max;
173 ///
174 /// assert_eq!(max(0..10), Some(9));
175 /// ```
max<I>(iterable: I) -> Option<I::Item> where I: IntoIterator, I::Item: Ord176 pub fn max<I>(iterable: I) -> Option<I::Item>
177     where I: IntoIterator,
178           I::Item: Ord
179 {
180     iterable.into_iter().max()
181 }
182 
183 /// Return the minimum value of the iterable.
184 ///
185 /// `IntoIterator` enabled version of `i.min()`.
186 ///
187 /// ```
188 /// use itertools::min;
189 ///
190 /// assert_eq!(min(0..10), Some(0));
191 /// ```
min<I>(iterable: I) -> Option<I::Item> where I: IntoIterator, I::Item: Ord192 pub fn min<I>(iterable: I) -> Option<I::Item>
193     where I: IntoIterator,
194           I::Item: Ord
195 {
196     iterable.into_iter().min()
197 }
198 
199 
200 /// Combine all iterator elements into one String, seperated by `sep`.
201 ///
202 /// `IntoIterator` enabled version of `iterable.join(sep)`.
203 ///
204 /// ```
205 /// use itertools::join;
206 ///
207 /// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
208 /// ```
209 #[cfg(feature = "use_std")]
join<I>(iterable: I, sep: &str) -> String where I: IntoIterator, I::Item: Display210 pub fn join<I>(iterable: I, sep: &str) -> String
211     where I: IntoIterator,
212           I::Item: Display
213 {
214     iterable.into_iter().join(sep)
215 }
216 
217 /// Sort all iterator elements into a new iterator in ascending order.
218 ///
219 /// `IntoIterator` enabled version of [`iterable.sorted()`][1].
220 ///
221 /// [1]: trait.Itertools.html#method.sorted
222 ///
223 /// ```
224 /// use itertools::sorted;
225 /// use itertools::assert_equal;
226 ///
227 /// assert_equal(sorted("rust".chars()), "rstu".chars());
228 /// ```
229 #[cfg(feature = "use_std")]
sorted<I>(iterable: I) -> VecIntoIter<I::Item> where I: IntoIterator, I::Item: Ord230 pub fn sorted<I>(iterable: I) -> VecIntoIter<I::Item>
231     where I: IntoIterator,
232           I::Item: Ord
233 {
234     iterable.into_iter().sorted()
235 }
236 
237