1# Changelog 2 3## 0.10.2 4 - Add `Itertools::multiunzip` (#362, #565) 5 - Add `intersperse` and `intersperse_with` free functions (#555) 6 - Add `Itertools::sorted_by_cached_key` (#424, #575) 7 - Specialize `ProcessResults::fold` (#563) 8 - Fix subtraction overflow in `DuplicatesBy::size_hint` (#552) 9 - Fix specialization tests (#574) 10 - More `Debug` impls (#573) 11 - Deprecate `fold1` (use `reduce` instead) (#580) 12 - Documentation fixes (`HomogenousTuple`, `into_group_map`, `into_group_map_by`, `MultiPeek::peek`) (#543 et al.) 13 14## 0.10.1 15 - Add `Itertools::contains` (#514) 16 - Add `Itertools::counts_by` (#515) 17 - Add `Itertools::partition_result` (#511) 18 - Add `Itertools::all_unique` (#241) 19 - Add `Itertools::duplicates` and `Itertools::duplicates_by` (#502) 20 - Add `chain!` (#525) 21 - Add `Itertools::at_most_one` (#523) 22 - Add `Itertools::flatten_ok` (#527) 23 - Add `EitherOrBoth::or_default` (#583) 24 - Add `Itertools::find_or_last` and `Itertools::find_or_first` (#535) 25 - Implement `FusedIterator` for `FilterOk`, `FilterMapOk`, `InterleaveShortest`, `KMergeBy`, `MergeBy`, `PadUsing`, `Positions`, `Product` , `RcIter`, `TupleWindows`, `Unique`, `UniqueBy`, `Update`, `WhileSome`, `Combinations`, `CombinationsWithReplacement`, `Powerset`, `RepeatN`, and `WithPosition` (#550) 26 - Implement `FusedIterator` for `Interleave`, `IntersperseWith`, and `ZipLongest` (#548) 27 28## 0.10.0 29 - **Increase minimum supported Rust version to 1.32.0** 30 - Improve macro hygiene (#507) 31 - Add `Itertools::powerset` (#335) 32 - Add `Itertools::sorted_unstable`, `Itertools::sorted_unstable_by`, and `Itertools::sorted_unstable_by_key` (#494) 33 - Implement `Error` for `ExactlyOneError` (#484) 34 - Undeprecate `Itertools::fold_while` (#476) 35 - Tuple-related adapters work for tuples of arity up to 12 (#475) 36 - `use_alloc` feature for users who have `alloc`, but not `std` (#474) 37 - Add `Itertools::k_smallest` (#473) 38 - Add `Itertools::into_grouping_map` and `GroupingMap` (#465) 39 - Add `Itertools::into_grouping_map_by` and `GroupingMapBy` (#465) 40 - Add `Itertools::counts` (#468) 41 - Add implementation of `DoubleEndedIterator` for `Unique` (#442) 42 - Add implementation of `DoubleEndedIterator` for `UniqueBy` (#442) 43 - Add implementation of `DoubleEndedIterator` for `Zip` (#346) 44 - Add `Itertools::multipeek` (#435) 45 - Add `Itertools::dedup_with_count` and `DedupWithCount` (#423) 46 - Add `Itertools::dedup_by_with_count` and `DedupByWithCount` (#423) 47 - Add `Itertools::intersperse_with` and `IntersperseWith` (#381) 48 - Add `Itertools::filter_ok` and `FilterOk` (#377) 49 - Add `Itertools::filter_map_ok` and `FilterMapOk` (#377) 50 - Deprecate `Itertools::fold_results`, use `Itertools::fold_ok` instead (#377) 51 - Deprecate `Itertools::map_results`, use `Itertools::map_ok` instead (#377) 52 - Deprecate `FoldResults`, use `FoldOk` instead (#377) 53 - Deprecate `MapResults`, use `MapOk` instead (#377) 54 - Add `Itertools::circular_tuple_windows` and `CircularTupleWindows` (#350) 55 - Add `peek_nth` and `PeekNth` (#303) 56 57## 0.9.0 58 - Fix potential overflow in `MergeJoinBy::size_hint` (#385) 59 - Add `derive(Clone)` where possible (#382) 60 - Add `try_collect` method (#394) 61 - Add `HomogeneousTuple` trait (#389) 62 - Fix `combinations(0)` and `combinations_with_replacement(0)` (#383) 63 - Don't require `ParitalEq` to the `Item` of `DedupBy` (#397) 64 - Implement missing specializations on the `PutBack` adaptor and on the `MergeJoinBy` iterator (#372) 65 - Add `position_*` methods (#412) 66 - Derive `Hash` for `EitherOrBoth` (#417) 67 - Increase minimum supported Rust version to 1.32.0 68 69## 0.8.2 70 - Use `slice::iter` instead of `into_iter` to avoid future breakage (#378, by @LukasKalbertodt) 71## 0.8.1 72 - Added a [`.exactly_one()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.exactly_one) iterator method that, on success, extracts the single value of an iterator ; by @Xaeroxe 73 - Added combinatory iterator adaptors: 74 - [`.permutations(k)`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.permutations): 75 76 `[0, 1, 2].iter().permutations(2)` yields 77 78 ```rust 79 [ 80 vec![0, 1], 81 vec![0, 2], 82 vec![1, 0], 83 vec![1, 2], 84 vec![2, 0], 85 vec![2, 1], 86 ] 87 ``` 88 89 ; by @tobz1000 90 91 - [`.combinations_with_replacement(k)`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.combinations_with_replacement): 92 93 `[0, 1, 2].iter().combinations_with_replacement(2)` yields 94 95 ```rust 96 [ 97 vec![0, 0], 98 vec![0, 1], 99 vec![0, 2], 100 vec![1, 1], 101 vec![1, 2], 102 vec![2, 2], 103 ] 104 ``` 105 106 ; by @tommilligan 107 108 - For reference, these methods join the already existing [`.combinations(k)`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.combinations): 109 110 `[0, 1, 2].iter().combinations(2)` yields 111 112 ```rust 113 [ 114 vec![0, 1], 115 vec![0, 2], 116 vec![1, 2], 117 ] 118 ``` 119 120 - Improved the performance of [`.fold()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.fold)-based internal iteration for the [`.intersperse()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.intersperse) iterator ; by @jswrenn 121 - Added [`.dedup_by()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.dedup_by), [`.merge_by()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.merge_by) and [`.kmerge_by()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.kmerge_by) adaptors that work like [`.dedup()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.dedup), [`.merge()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.merge) and [`.kmerge()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.kmerge), but taking an additional custom comparison closure parameter. ; by @phimuemue 122 - Improved the performance of [`.all_equal()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.all_equal) ; by @fyrchik 123 - Loosened the bounds on [`.partition_map()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.partition_map) to take just a `FnMut` closure rather than a `Fn` closure, and made its implementation use internal iteration for better performance ; by @danielhenrymantilla 124 - Added convenience methods to [`EitherOrBoth`](https://docs.rs/itertools/0.8.1/itertools/enum.EitherOrBoth.html) elements yielded from the [`.zip_longest()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.zip_longest) iterator adaptor ; by @Avi-D-coder 125 - Added [`.sum1()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.sum1) and [`.product1()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.product1) iterator methods that respectively try to return the sum and the product of the elements of an iterator **when it is not empty**, otherwise they return `None` ; by @Emerentius 126## 0.8.0 127 - Added new adaptor `.map_into()` for conversions using `Into` by @vorner 128 - Improved `Itertools` docs by @JohnHeitmann 129 - The return type of `.sorted_by_by_key()` is now an iterator, not a Vec. 130 - The return type of the `izip!(x, y)` macro with exactly two arguments is now the usual `Iterator::zip`. 131 - Remove `.flatten()` in favour of std's `.flatten()` 132 - Deprecate `.foreach()` in favour of std's `.for_each()` 133 - Deprecate `.step()` in favour of std's `.step_by()` 134 - Deprecate `repeat_call` in favour of std's `repeat_with` 135 - Deprecate `.fold_while()` in favour of std's `.try_fold()` 136 - Require Rust 1.24 as minimal version. 137## 0.7.11 138 - Add convenience methods to `EitherOrBoth`, making it more similar to `Option` and `Either` by @jethrogb 139## 0.7.10 140 - No changes. 141## 0.7.9 142 - New inclusion policy: See the readme about suggesting features for std before accepting them in itertools. 143 - The `FoldWhile` type now implements `Eq` and `PartialEq` by @jturner314 144## 0.7.8 145 - Add new iterator method `.tree_fold1()` which is like `.fold1()` except items are combined in a tree structure (see its docs). By @scottmcm 146 - Add more `Debug` impls by @phimuemue: KMerge, KMergeBy, MergeJoinBy, ConsTuples, Intersperse, ProcessResults, RcIter, Tee, TupleWindows, Tee, ZipLongest, ZipEq, Zip. 147## 0.7.7 148 - Add new iterator method `.into_group_map() -> HashMap<K, Vec<V>>` which turns an iterator of `(K, V)` elements into such a hash table, where values are grouped by key. By @tobz1000 149 - Add new free function `flatten` for the `.flatten()` adaptor. **NOTE:** recent Rust nightlies have `Iterator::flatten` and thus a clash with our flatten adaptor. One workaround is to use the itertools `flatten` free function. 150## 0.7.6 151 - Add new adaptor `.multi_cartesian_product()` which is an n-ary product iterator by @tobz1000 152 - Add new method `.sorted_by_key()` by @Xion 153 - Provide simpler and faster `.count()` for `.unique()` and `.unique_by()` 154## 0.7.5 155 - `.multipeek()` now implements `PeekingNext`, by @nicopap. 156## 0.7.4 157 - Add new adaptor `.update()` by @lucasem; this adaptor is used to modify an element before passing it on in an iterator chain. 158## 0.7.3 159 - Add new method `.collect_tuple()` by @matklad; it makes a tuple out of the iterator's elements if the number of them matches **exactly**. 160 - Implement `fold` and `collect` for `.map_results()` which means it reuses the code of the standard `.map()` for these methods. 161## 0.7.2 162 - Add new adaptor `.merge_join_by` by @srijs; a heterogeneous merge join for two ordered sequences. 163## 0.7.1 164 - Iterator adaptors and iterators in itertools now use the same `must_use` reminder that the standard library adaptors do, by @matematikaedit and @bluss *“iterator adaptors are lazy and do nothing unless consumed”*. 165## 0.7.0 166 - Faster `izip!()` by @krdln 167 - `izip!()` is now a wrapper for repeated regular `.zip()` and a single `.map()`. This means it optimizes as well as the standard library `.zip()` it uses. **Note:** `multizip` and `izip!()` are now different! The former has a named type but the latter optimizes better. 168 - Faster `.unique()` 169 - `no_std` support, which is opt-in! 170 - Many lovable features are still there without std, like `izip!()` or `.format()` or `.merge()`, but not those that use collections. 171 - Trait bounds were required up front instead of just on the type: `group_by`'s `PartialEq` by @Phlosioneer and `repeat_call`'s `FnMut`. 172 - Removed deprecated constructor `Zip::new` — use `izip!()` or `multizip()` 173## 0.6.5 174 - Fix bug in `.cartesian_product()`'s fold (which only was visible for unfused iterators). 175## 0.6.4 176 - Add specific `fold` implementations for `.cartesian_product()` and `cons_tuples()`, which improves their performance in fold, foreach, and iterator consumers derived from them. 177## 0.6.3 178 - Add iterator adaptor `.positions(predicate)` by @tmccombs 179## 0.6.2 180 - Add function `process_results` which can “lift” a function of the regular values of an iterator so that it can process the `Ok` values from an iterator of `Results` instead, by @shepmaster 181 - Add iterator method `.concat()` which combines all iterator elements into a single collection using the `Extend` trait, by @srijs 182## 0.6.1 183 - Better size hint testing and subsequent size hint bugfixes by @rkarp. Fixes bugs in product, `interleave_shortest` size hints. 184 - New iterator method `.all_equal()` by @phimuemue 185## 0.6.0 186 - Deprecated names were removed in favour of their replacements 187 - `.flatten()` does not implement double ended iteration anymore 188 - `.fold_while()` uses `&mut self` and returns `FoldWhile<T>`, for composability #168 189 - `.foreach()` and `.fold1()` use `self`, like `.fold()` does. 190 - `.combinations(0)` now produces a single empty vector. #174 191## 0.5.10 192 - Add itertools method `.kmerge_by()` (and corresponding free function) 193 - Relaxed trait requirement of `.kmerge()` and `.minmax()` to PartialOrd. 194## 0.5.9 195 - Add multipeek method `.reset_peek()` 196 - Add categories 197## 0.5.8 198 - Add iterator adaptor `.peeking_take_while()` and its trait `PeekingNext`. 199## 0.5.7 200 - Add iterator adaptor `.with_position()` 201 - Fix multipeek's performance for long peeks by using `VecDeque`. 202## 0.5.6 203 - Add `.map_results()` 204## 0.5.5 205 - Many more adaptors now implement `Debug` 206 - Add free function constructor `repeat_n`. `RepeatN::new` is now deprecated. 207## 0.5.4 208 - Add infinite generator function `iterate`, that takes a seed and a closure. 209## 0.5.3 210 - Special-cased `.fold()` for flatten and put back. `.foreach()` now uses fold on the iterator, to pick up any iterator specific loop implementation. 211 - `.combinations(n)` asserts up front that `n != 0`, instead of running into an error on the second iterator element. 212## 0.5.2 213 - Add `.tuples::<T>()` that iterates by two, three or four elements at a time (where `T` is a tuple type). 214 - Add `.tuple_windows::<T>()` that iterates using a window of the two, three or four most recent elements. 215 - Add `.next_tuple::<T>()` method, that picks the next two, three or four elements in one go. 216 - `.interleave()` now has an accurate size hint. 217## 0.5.1 218 - Workaround module/function name clash that made racer crash on completing itertools. Only internal changes needed. 219## 0.5.0 220 - [Release announcement](https://bluss.github.io/rust/2016/09/26/itertools-0.5.0/) 221 - Renamed: 222 - `combinations` is now `tuple_combinations` 223 - `combinations_n` to `combinations` 224 - `group_by_lazy`, `chunks_lazy` to `group_by`, `chunks` 225 - `Unfold::new` to `unfold()` 226 - `RepeatCall::new` to `repeat_call()` 227 - `Zip::new` to `multizip` 228 - `PutBack::new`, `PutBackN::new` to `put_back`, `put_back_n` 229 - `PutBack::with_value` is now a builder setter, not a constructor 230 - `MultiPeek::new`, `.multipeek()` to `multipeek()` 231 - `format` to `format_with` and `format_default` to `format` 232 - `.into_rc()` to `rciter` 233 - `Partition` enum is now `Either` 234 - Module reorganization: 235 - All iterator structs are under `itertools::structs` but also reexported to the top level, for backwards compatibility 236 - All free functions are reexported at the root, `itertools::free` will be removed in the next version 237 - Removed: 238 - `ZipSlices`, use `.zip()` instead 239 - `.enumerate_from()`, `ZipTrusted`, due to being unstable 240 - `.mend_slices()`, moved to crate `odds` 241 - Stride, StrideMut, moved to crate `odds` 242 - `linspace()`, moved to crate `itertools-num` 243 - `.sort_by()`, use `.sorted_by()` 244 - `.is_empty_hint()`, use `.size_hint()` 245 - `.dropn()`, use `.dropping()` 246 - `.map_fn()`, use `.map()` 247 - `.slice()`, use `.take()` / `.skip()` 248 - helper traits in `misc` 249 - `new` constructors on iterator structs, use `Itertools` trait or free functions instead 250 - `itertools::size_hint` is now private 251 - Behaviour changes: 252 - `format` and `format_with` helpers now panic if you try to format them more than once. 253 - `repeat_call` is not double ended anymore 254 - New features: 255 - tuple flattening iterator is constructible with `cons_tuples` 256 - itertools reexports `Either` from the `either` crate. `Either<L, R>` is an iterator when `L, R` are. 257 - `MinMaxResult` now implements `Copy` and `Clone` 258 - `tuple_combinations` supports 1-4 tuples of combinations (previously just 2) 259## 0.4.19 260 - Add `.minmax_by()` 261 - Add `itertools::free::cloned` 262 - Add `itertools::free::rciter` 263 - Improve `.step(n)` slightly to take advantage of specialized Fuse better. 264## 0.4.18 265 - Only changes related to the "unstable" crate feature. This feature is more or less deprecated. 266 - Use deprecated warnings when unstable is enabled. `.enumerate_from()` will be removed imminently since it's using a deprecated libstd trait. 267## 0.4.17 268 - Fix bug in `.kmerge()` that caused it to often produce the wrong order #134 269## 0.4.16 270 - Improve precision of the `interleave_shortest` adaptor's size hint (it is now computed exactly when possible). 271## 0.4.15 272 - Fixup on top of the workaround in 0.4.14. A function in `itertools::free` was removed by mistake and now it is added back again. 273## 0.4.14 274 - Workaround an upstream regression in a Rust nightly build that broke compilation of of `itertools::free::{interleave, merge}` 275## 0.4.13 276 - Add `.minmax()` and `.minmax_by_key()`, iterator methods for finding both minimum and maximum in one scan. 277 - Add `.format_default()`, a simpler version of `.format()` (lazy formatting for iterators). 278## 0.4.12 279 - Add `.zip_eq()`, an adaptor like `.zip()` except it ensures iterators of inequal length don't pass silently (instead it panics). 280 - Add `.fold_while()`, an iterator method that is a fold that can short-circuit. 281 - Add `.partition_map()`, an iterator method that can separate elements into two collections. 282## 0.4.11 283 - Add `.get()` for `Stride{,Mut}` and `.get_mut()` for `StrideMut` 284## 0.4.10 285 - Improve performance of `.kmerge()` 286## 0.4.9 287 - Add k-ary merge adaptor `.kmerge()` 288 - Fix a bug in `.islice()` with ranges `a..b` where a `> b`. 289## 0.4.8 290 - Implement `Clone`, `Debug` for `Linspace` 291## 0.4.7 292 - Add function `diff_with()` that compares two iterators 293 - Add `.combinations_n()`, an n-ary combinations iterator 294 - Add methods `PutBack::with_value` and `PutBack::into_parts`. 295## 0.4.6 296 - Add method `.sorted()` 297 - Add module `itertools::free` with free function variants of common iterator adaptors and methods. For example `enumerate(iterable)`, `rev(iterable)`, and so on. 298## 0.4.5 299 - Add `.flatten()` 300## 0.4.4 301 - Allow composing `ZipSlices` with itself 302## 0.4.3 303 - Write `iproduct!()` as a single expression; this allows temporary values in its arguments. 304## 0.4.2 305 - Add `.fold_options()` 306 - Require Rust 1.1 or later 307## 0.4.1 308 - Update `.dropping()` to take advantage of `.nth()` 309## 0.4.0 310 - `.merge()`, `.unique()` and `.dedup()` now perform better due to not using function pointers 311 - Add free functions `enumerate()` and `rev()` 312 - Breaking changes: 313 - Return types of `.merge()` and `.merge_by()` renamed and changed 314 - Method `Merge::new` removed 315 - `.merge_by()` now takes a closure that returns bool. 316 - Return type of `.dedup()` changed 317 - Return type of `.mend_slices()` changed 318 - Return type of `.unique()` changed 319 - Removed function `times()`, struct `Times`: use a range instead 320 - Removed deprecated macro `icompr!()` 321 - Removed deprecated `FnMap` and method `.fn_map()`: use `.map_fn()` 322 - `.interleave_shortest()` is no longer guaranteed to act like fused 323## 0.3.25 324 - Rename `.sort_by()` to `.sorted_by()`. Old name is deprecated. 325 - Fix well-formedness warnings from RFC 1214, no user visible impact 326## 0.3.24 327 - Improve performance of `.merge()`'s ordering function slightly 328## 0.3.23 329 - Added `.chunks()`, similar to (and based on) `.group_by_lazy()`. 330 - Tweak linspace to match numpy.linspace and make it double ended. 331## 0.3.22 332 - Added `ZipSlices`, a fast zip for slices 333## 0.3.21 334 - Remove `Debug` impl for `Format`, it will have different use later 335## 0.3.20 336 - Optimize `.group_by_lazy()` 337## 0.3.19 338 - Added `.group_by_lazy()`, a possibly nonallocating group by 339 - Added `.format()`, a nonallocating formatting helper for iterators 340 - Remove uses of `RandomAccessIterator` since it has been deprecated in Rust. 341## 0.3.17 342 - Added (adopted) `Unfold` from Rust 343## 0.3.16 344 - Added adaptors `.unique()`, `.unique_by()` 345## 0.3.15 346 - Added method `.sort_by()` 347## 0.3.14 348 - Added adaptor `.while_some()` 349## 0.3.13 350 - Added adaptor `.interleave_shortest()` 351 - Added adaptor `.pad_using()` 352## 0.3.11 353 - Added `assert_equal` function 354## 0.3.10 355 - Bugfix `.combinations()` `size_hint`. 356## 0.3.8 357 - Added source `RepeatCall` 358## 0.3.7 359 - Added adaptor `PutBackN` 360 - Added adaptor `.combinations()` 361## 0.3.6 362 - Added `itertools::partition`, partition a sequence in place based on a predicate. 363 - Deprecate `icompr!()` with no replacement. 364## 0.3.5 365 - `.map_fn()` replaces deprecated `.fn_map()`. 366## 0.3.4 367 - `.take_while_ref()` *by-ref adaptor* 368 - `.coalesce()` *adaptor* 369 - `.mend_slices()` *adaptor* 370## 0.3.3 371 - `.dropping_back()` *method* 372 - `.fold1()` *method* 373 - `.is_empty_hint()` *method* 374