]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
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 | /// ``` | |
42 | 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 | /// ``` | |
59 | 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 | /// ``` | |
78 | 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 | /// ``` | |
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 | /// ``` | |
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 | /// ``` | |
128 | 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 | /// ``` | |
144 | 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 | /// ``` | |
160 | 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 | /// ``` | |
176 | 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 | /// ``` | |
192 | 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")] | |
210 | 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")] | |
230 | 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 |