1# Changelog 2 3## 0.13.0 4 5### Breaking 6- Removed implementation of `DoubleEndedIterator` for `ConsTuples` (#853) 7- Made `MultiProduct` fused and fixed on an empty iterator (#835, #834) 8- Changed `iproduct!` to return tuples for maxi one iterator too (#870) 9- Changed `PutBack::put_back` to return the old value (#880) 10- Removed deprecated `repeat_call, Itertools::{foreach, step, map_results, fold_results}` (#878) 11- Removed `TakeWhileInclusive::new` (#912) 12 13### Added 14- Added `Itertools::{smallest_by, smallest_by_key, largest, largest_by, largest_by_key}` (#654, #885) 15- Added `Itertools::tail` (#899) 16- Implemented `DoubleEndedIterator` for `ProcessResults` (#910) 17- Implemented `Debug` for `FormatWith` (#931) 18- Added `Itertools::get` (#891) 19 20### Changed 21- Deprecated `Itertools::group_by` (renamed `chunk_by`) (#866, #879) 22- Deprecated `unfold` (use `std::iter::from_fn` instead) (#871) 23- Optimized `GroupingMapBy` (#873, #876) 24- Relaxed `Fn` bounds to `FnMut` in `diff_with, Itertools::into_group_map_by` (#886) 25- Relaxed `Debug/Clone` bounds for `MapInto` (#889) 26- Documented the `use_alloc` feature (#887) 27- Optimized `Itertools::set_from` (#888) 28- Removed badges in `README.md` (#890) 29- Added "no-std" categories in `Cargo.toml` (#894) 30- Fixed `Itertools::k_smallest` on short unfused iterators (#900) 31- Deprecated `Itertools::tree_fold1` (renamed `tree_reduce`) (#895) 32- Deprecated `GroupingMap::fold_first` (renamed `reduce`) (#902) 33- Fixed `Itertools::k_smallest(0)` to consume the iterator, optimized `Itertools::k_smallest(1)` (#909) 34- Specialized `Combinations::nth` (#914) 35- Specialized `MergeBy::fold` (#920) 36- Specialized `CombinationsWithReplacement::nth` (#923) 37- Specialized `FlattenOk::{fold, rfold}` (#927) 38- Specialized `Powerset::nth` (#924) 39- Documentation fixes (#882, #936) 40- Fixed `assert_equal` for iterators longer than `i32::MAX` (#932) 41- Updated the `must_use` message of non-lazy `KMergeBy` and `TupleCombinations` (#939) 42 43### Notable Internal Changes 44- Tested iterator laziness (#792) 45- Created `CONTRIBUTING.md` (#767) 46 47## 0.12.1 48 49### Added 50- Documented iteration order guarantee for `Itertools::[tuple_]combinations` (#822) 51- Documented possible panic in `iterate` (#842) 52- Implemented `Clone` and `Debug` for `Diff` (#845) 53- Implemented `Debug` for `WithPosition` (#859) 54- Implemented `Eq` for `MinMaxResult` (#838) 55- Implemented `From<EitherOrBoth<A, B>>` for `Option<Either<A, B>>` (#843) 56- Implemented `PeekingNext` for `RepeatN` (#855) 57 58### Changed 59- Made `CoalesceBy` lazy (#801) 60- Optimized `Filter[Map]Ok::next`, `Itertools::partition`, `Unique[By]::next[_back]` (#818) 61- Optimized `Itertools::find_position` (#837) 62- Optimized `Positions::next[_back]` (#816) 63- Optimized `ZipLongest::fold` (#854) 64- Relaxed `Debug` bounds for `GroupingMapBy` (#860) 65- Specialized `ExactlyOneError::fold` (#826) 66- Specialized `Interleave[Shortest]::fold` (#849) 67- Specialized `MultiPeek::fold` (#820) 68- Specialized `PadUsing::[r]fold` (#825) 69- Specialized `PeekNth::fold` (#824) 70- Specialized `Positions::[r]fold` (#813) 71- Specialized `PutBackN::fold` (#823) 72- Specialized `RepeatN::[r]fold` (#821) 73- Specialized `TakeWhileInclusive::fold` (#851) 74- Specialized `ZipLongest::rfold` (#848) 75 76### Notable Internal Changes 77- Added test coverage in CI (#847, #856) 78- Added semver check in CI (#784) 79- Enforced `clippy` in CI (#740) 80- Enforced `rustdoc` in CI (#840) 81- Improved specialization tests (#807) 82- More specialization benchmarks (#806) 83 84## 0.12.0 85 86### Breaking 87- Made `take_while_inclusive` consume iterator by value (#709) 88- Added `Clone` bound to `Unique` (#777) 89 90### Added 91- Added `Itertools::try_len` (#723) 92- Added free function `sort_unstable` (#796) 93- Added `GroupMap::fold_with` (#778, #785) 94- Added `PeekNth::{peek_mut, peek_nth_mut}` (#716) 95- Added `PeekNth::{next_if, next_if_eq}` (#734) 96- Added conversion into `(Option<A>,Option<B>)` to `EitherOrBoth` (#713) 97- Added conversion from `Either<A, B>` to `EitherOrBoth<A, B>` (#715) 98- Implemented `ExactSizeIterator` for `Tuples` (#761) 99- Implemented `ExactSizeIterator` for `(Circular)TupleWindows` (#752) 100- Made `EitherOrBoth<T>` a shorthand for `EitherOrBoth<T, T>` (#719) 101 102### Changed 103- Added missing `#[must_use]` annotations on iterator adaptors (#794) 104- Made `Combinations` lazy (#795) 105- Made `Intersperse(With)` lazy (#797) 106- Made `Permutations` lazy (#793) 107- Made `Product` lazy (#800) 108- Made `TupleWindows` lazy (#602) 109- Specialized `Combinations::{count, size_hint}` (#729) 110- Specialized `CombinationsWithReplacement::{count, size_hint}` (#737) 111- Specialized `Powerset::fold` (#765) 112- Specialized `Powerset::count` (#735) 113- Specialized `TupleCombinations::{count, size_hint}` (#763) 114- Specialized `TupleCombinations::fold` (#775) 115- Specialized `WhileSome::fold` (#780) 116- Specialized `WithPosition::fold` (#772) 117- Specialized `ZipLongest::fold` (#774) 118- Changed `{min, max}_set*` operations require `alloc` feature, instead of `std` (#760) 119- Improved documentation of `tree_fold1` (#787) 120- Improved documentation of `permutations` (#724) 121- Fixed typo in documentation of `multiunzip` (#770) 122 123### Notable Internal Changes 124- Improved specialization tests (#799, #786, #782) 125- Simplified implementation of `Permutations` (#739, #748, #790) 126- Combined `Merge`/`MergeBy`/`MergeJoinBy` implementations (#736) 127- Simplified `Permutations::size_hint` (#739) 128- Fix wrapping arithmetic in benchmarks (#770) 129- Enforced `rustfmt` in CI (#751) 130- Disallowed compile warnings in CI (#720) 131- Used `cargo hack` to check MSRV (#754) 132 133## 0.11.0 134 135### Breaking 136- Make `Itertools::merge_join_by` also accept functions returning bool (#704) 137- Implement `PeekingNext` transitively over mutable references (#643) 138- Change `with_position` to yield `(Position, Item)` instead of `Position<Item>` (#699) 139 140### Added 141- Add `Itertools::take_while_inclusive` (#616) 142- Implement `PeekingNext` for `PeekingTakeWhile` (#644) 143- Add `EitherOrBoth::{just_left, just_right, into_left, into_right, as_deref, as_deref_mut, left_or_insert, right_or_insert, left_or_insert_with, right_or_insert_with, insert_left, insert_right, insert_both}` (#629) 144- Implement `Clone` for `CircularTupleWindows` (#686) 145- Implement `Clone` for `Chunks` (#683) 146- Add `Itertools::process_results` (#680) 147 148### Changed 149- Use `Cell` instead of `RefCell` in `Format` and `FormatWith` (#608) 150- CI tweaks (#674, #675) 151- Document and test the difference between stable and unstable sorts (#653) 152- Fix documentation error on `Itertools::max_set_by_key` (#692) 153- Move MSRV metadata to `Cargo.toml` (#672) 154- Implement `equal` with `Iterator::eq` (#591) 155 156## 0.10.5 157 - Maintenance 158 159## 0.10.4 160 - Add `EitherOrBoth::or` and `EitherOrBoth::or_else` (#593) 161 - Add `min_set`, `max_set` et al. (#613, #323) 162 - Use `either/use_std` (#628) 163 - Documentation fixes (#612, #625, #632, #633, #634, #638) 164 - Code maintenance (#623, #624, #627, #630) 165 166## 0.10.3 167 - Maintenance 168 169## 0.10.2 170 - Add `Itertools::multiunzip` (#362, #565) 171 - Add `intersperse` and `intersperse_with` free functions (#555) 172 - Add `Itertools::sorted_by_cached_key` (#424, #575) 173 - Specialize `ProcessResults::fold` (#563) 174 - Fix subtraction overflow in `DuplicatesBy::size_hint` (#552) 175 - Fix specialization tests (#574) 176 - More `Debug` impls (#573) 177 - Deprecate `fold1` (use `reduce` instead) (#580) 178 - Documentation fixes (`HomogenousTuple`, `into_group_map`, `into_group_map_by`, `MultiPeek::peek`) (#543 et al.) 179 180## 0.10.1 181 - Add `Itertools::contains` (#514) 182 - Add `Itertools::counts_by` (#515) 183 - Add `Itertools::partition_result` (#511) 184 - Add `Itertools::all_unique` (#241) 185 - Add `Itertools::duplicates` and `Itertools::duplicates_by` (#502) 186 - Add `chain!` (#525) 187 - Add `Itertools::at_most_one` (#523) 188 - Add `Itertools::flatten_ok` (#527) 189 - Add `EitherOrBoth::or_default` (#583) 190 - Add `Itertools::find_or_last` and `Itertools::find_or_first` (#535) 191 - Implement `FusedIterator` for `FilterOk`, `FilterMapOk`, `InterleaveShortest`, `KMergeBy`, `MergeBy`, `PadUsing`, `Positions`, `Product` , `RcIter`, `TupleWindows`, `Unique`, `UniqueBy`, `Update`, `WhileSome`, `Combinations`, `CombinationsWithReplacement`, `Powerset`, `RepeatN`, and `WithPosition` (#550) 192 - Implement `FusedIterator` for `Interleave`, `IntersperseWith`, and `ZipLongest` (#548) 193 194## 0.10.0 195 - **Increase minimum supported Rust version to 1.32.0** 196 - Improve macro hygiene (#507) 197 - Add `Itertools::powerset` (#335) 198 - Add `Itertools::sorted_unstable`, `Itertools::sorted_unstable_by`, and `Itertools::sorted_unstable_by_key` (#494) 199 - Implement `Error` for `ExactlyOneError` (#484) 200 - Undeprecate `Itertools::fold_while` (#476) 201 - Tuple-related adapters work for tuples of arity up to 12 (#475) 202 - `use_alloc` feature for users who have `alloc`, but not `std` (#474) 203 - Add `Itertools::k_smallest` (#473) 204 - Add `Itertools::into_grouping_map` and `GroupingMap` (#465) 205 - Add `Itertools::into_grouping_map_by` and `GroupingMapBy` (#465) 206 - Add `Itertools::counts` (#468) 207 - Add implementation of `DoubleEndedIterator` for `Unique` (#442) 208 - Add implementation of `DoubleEndedIterator` for `UniqueBy` (#442) 209 - Add implementation of `DoubleEndedIterator` for `Zip` (#346) 210 - Add `Itertools::multipeek` (#435) 211 - Add `Itertools::dedup_with_count` and `DedupWithCount` (#423) 212 - Add `Itertools::dedup_by_with_count` and `DedupByWithCount` (#423) 213 - Add `Itertools::intersperse_with` and `IntersperseWith` (#381) 214 - Add `Itertools::filter_ok` and `FilterOk` (#377) 215 - Add `Itertools::filter_map_ok` and `FilterMapOk` (#377) 216 - Deprecate `Itertools::fold_results`, use `Itertools::fold_ok` instead (#377) 217 - Deprecate `Itertools::map_results`, use `Itertools::map_ok` instead (#377) 218 - Deprecate `FoldResults`, use `FoldOk` instead (#377) 219 - Deprecate `MapResults`, use `MapOk` instead (#377) 220 - Add `Itertools::circular_tuple_windows` and `CircularTupleWindows` (#350) 221 - Add `peek_nth` and `PeekNth` (#303) 222 223## 0.9.0 224 - Fix potential overflow in `MergeJoinBy::size_hint` (#385) 225 - Add `derive(Clone)` where possible (#382) 226 - Add `try_collect` method (#394) 227 - Add `HomogeneousTuple` trait (#389) 228 - Fix `combinations(0)` and `combinations_with_replacement(0)` (#383) 229 - Don't require `ParitalEq` to the `Item` of `DedupBy` (#397) 230 - Implement missing specializations on the `PutBack` adaptor and on the `MergeJoinBy` iterator (#372) 231 - Add `position_*` methods (#412) 232 - Derive `Hash` for `EitherOrBoth` (#417) 233 - Increase minimum supported Rust version to 1.32.0 234 235## 0.8.2 236 - Use `slice::iter` instead of `into_iter` to avoid future breakage (#378, by @LukasKalbertodt) 237## 0.8.1 238 - 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 239 - Added combinatory iterator adaptors: 240 - [`.permutations(k)`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.permutations): 241 242 `[0, 1, 2].iter().permutations(2)` yields 243 244 ```rust 245 [ 246 vec![0, 1], 247 vec![0, 2], 248 vec![1, 0], 249 vec![1, 2], 250 vec![2, 0], 251 vec![2, 1], 252 ] 253 ``` 254 255 ; by @tobz1000 256 257 - [`.combinations_with_replacement(k)`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.combinations_with_replacement): 258 259 `[0, 1, 2].iter().combinations_with_replacement(2)` yields 260 261 ```rust 262 [ 263 vec![0, 0], 264 vec![0, 1], 265 vec![0, 2], 266 vec![1, 1], 267 vec![1, 2], 268 vec![2, 2], 269 ] 270 ``` 271 272 ; by @tommilligan 273 274 - For reference, these methods join the already existing [`.combinations(k)`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.combinations): 275 276 `[0, 1, 2].iter().combinations(2)` yields 277 278 ```rust 279 [ 280 vec![0, 1], 281 vec![0, 2], 282 vec![1, 2], 283 ] 284 ``` 285 286 - 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 287 - 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 288 - Improved the performance of [`.all_equal()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.all_equal) ; by @fyrchik 289 - 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 290 - 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 291 - 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 292## 0.8.0 293 - Added new adaptor `.map_into()` for conversions using `Into` by @vorner 294 - Improved `Itertools` docs by @JohnHeitmann 295 - The return type of `.sorted_by_by_key()` is now an iterator, not a Vec. 296 - The return type of the `izip!(x, y)` macro with exactly two arguments is now the usual `Iterator::zip`. 297 - Remove `.flatten()` in favour of std's `.flatten()` 298 - Deprecate `.foreach()` in favour of std's `.for_each()` 299 - Deprecate `.step()` in favour of std's `.step_by()` 300 - Deprecate `repeat_call` in favour of std's `repeat_with` 301 - Deprecate `.fold_while()` in favour of std's `.try_fold()` 302 - Require Rust 1.24 as minimal version. 303## 0.7.11 304 - Add convenience methods to `EitherOrBoth`, making it more similar to `Option` and `Either` by @jethrogb 305## 0.7.10 306 - No changes. 307## 0.7.9 308 - New inclusion policy: See the readme about suggesting features for std before accepting them in itertools. 309 - The `FoldWhile` type now implements `Eq` and `PartialEq` by @jturner314 310## 0.7.8 311 - Add new iterator method `.tree_fold1()` which is like `.fold1()` except items are combined in a tree structure (see its docs). By @scottmcm 312 - Add more `Debug` impls by @phimuemue: KMerge, KMergeBy, MergeJoinBy, ConsTuples, Intersperse, ProcessResults, RcIter, Tee, TupleWindows, Tee, ZipLongest, ZipEq, Zip. 313## 0.7.7 314 - 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 315 - 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. 316## 0.7.6 317 - Add new adaptor `.multi_cartesian_product()` which is an n-ary product iterator by @tobz1000 318 - Add new method `.sorted_by_key()` by @Xion 319 - Provide simpler and faster `.count()` for `.unique()` and `.unique_by()` 320## 0.7.5 321 - `.multipeek()` now implements `PeekingNext`, by @nicopap. 322## 0.7.4 323 - Add new adaptor `.update()` by @lucasem; this adaptor is used to modify an element before passing it on in an iterator chain. 324## 0.7.3 325 - Add new method `.collect_tuple()` by @matklad; it makes a tuple out of the iterator's elements if the number of them matches **exactly**. 326 - Implement `fold` and `collect` for `.map_results()` which means it reuses the code of the standard `.map()` for these methods. 327## 0.7.2 328 - Add new adaptor `.merge_join_by` by @srijs; a heterogeneous merge join for two ordered sequences. 329## 0.7.1 330 - 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”*. 331## 0.7.0 332 - Faster `izip!()` by @krdln 333 - `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. 334 - Faster `.unique()` 335 - `no_std` support, which is opt-in! 336 - Many lovable features are still there without std, like `izip!()` or `.format()` or `.merge()`, but not those that use collections. 337 - Trait bounds were required up front instead of just on the type: `group_by`'s `PartialEq` by @Phlosioneer and `repeat_call`'s `FnMut`. 338 - Removed deprecated constructor `Zip::new` — use `izip!()` or `multizip()` 339## 0.6.5 340 - Fix bug in `.cartesian_product()`'s fold (which only was visible for unfused iterators). 341## 0.6.4 342 - Add specific `fold` implementations for `.cartesian_product()` and `cons_tuples()`, which improves their performance in fold, foreach, and iterator consumers derived from them. 343## 0.6.3 344 - Add iterator adaptor `.positions(predicate)` by @tmccombs 345## 0.6.2 346 - 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 347 - Add iterator method `.concat()` which combines all iterator elements into a single collection using the `Extend` trait, by @srijs 348## 0.6.1 349 - Better size hint testing and subsequent size hint bugfixes by @rkarp. Fixes bugs in product, `interleave_shortest` size hints. 350 - New iterator method `.all_equal()` by @phimuemue 351## 0.6.0 352 - Deprecated names were removed in favour of their replacements 353 - `.flatten()` does not implement double ended iteration anymore 354 - `.fold_while()` uses `&mut self` and returns `FoldWhile<T>`, for composability #168 355 - `.foreach()` and `.fold1()` use `self`, like `.fold()` does. 356 - `.combinations(0)` now produces a single empty vector. #174 357## 0.5.10 358 - Add itertools method `.kmerge_by()` (and corresponding free function) 359 - Relaxed trait requirement of `.kmerge()` and `.minmax()` to PartialOrd. 360## 0.5.9 361 - Add multipeek method `.reset_peek()` 362 - Add categories 363## 0.5.8 364 - Add iterator adaptor `.peeking_take_while()` and its trait `PeekingNext`. 365## 0.5.7 366 - Add iterator adaptor `.with_position()` 367 - Fix multipeek's performance for long peeks by using `VecDeque`. 368## 0.5.6 369 - Add `.map_results()` 370## 0.5.5 371 - Many more adaptors now implement `Debug` 372 - Add free function constructor `repeat_n`. `RepeatN::new` is now deprecated. 373## 0.5.4 374 - Add infinite generator function `iterate`, that takes a seed and a closure. 375## 0.5.3 376 - Special-cased `.fold()` for flatten and put back. `.foreach()` now uses fold on the iterator, to pick up any iterator specific loop implementation. 377 - `.combinations(n)` asserts up front that `n != 0`, instead of running into an error on the second iterator element. 378## 0.5.2 379 - Add `.tuples::<T>()` that iterates by two, three or four elements at a time (where `T` is a tuple type). 380 - Add `.tuple_windows::<T>()` that iterates using a window of the two, three or four most recent elements. 381 - Add `.next_tuple::<T>()` method, that picks the next two, three or four elements in one go. 382 - `.interleave()` now has an accurate size hint. 383## 0.5.1 384 - Workaround module/function name clash that made racer crash on completing itertools. Only internal changes needed. 385## 0.5.0 386 - [Release announcement](https://bluss.github.io/rust/2016/09/26/itertools-0.5.0/) 387 - Renamed: 388 - `combinations` is now `tuple_combinations` 389 - `combinations_n` to `combinations` 390 - `group_by_lazy`, `chunks_lazy` to `group_by`, `chunks` 391 - `Unfold::new` to `unfold()` 392 - `RepeatCall::new` to `repeat_call()` 393 - `Zip::new` to `multizip` 394 - `PutBack::new`, `PutBackN::new` to `put_back`, `put_back_n` 395 - `PutBack::with_value` is now a builder setter, not a constructor 396 - `MultiPeek::new`, `.multipeek()` to `multipeek()` 397 - `format` to `format_with` and `format_default` to `format` 398 - `.into_rc()` to `rciter` 399 - `Partition` enum is now `Either` 400 - Module reorganization: 401 - All iterator structs are under `itertools::structs` but also reexported to the top level, for backwards compatibility 402 - All free functions are reexported at the root, `itertools::free` will be removed in the next version 403 - Removed: 404 - `ZipSlices`, use `.zip()` instead 405 - `.enumerate_from()`, `ZipTrusted`, due to being unstable 406 - `.mend_slices()`, moved to crate `odds` 407 - Stride, StrideMut, moved to crate `odds` 408 - `linspace()`, moved to crate `itertools-num` 409 - `.sort_by()`, use `.sorted_by()` 410 - `.is_empty_hint()`, use `.size_hint()` 411 - `.dropn()`, use `.dropping()` 412 - `.map_fn()`, use `.map()` 413 - `.slice()`, use `.take()` / `.skip()` 414 - helper traits in `misc` 415 - `new` constructors on iterator structs, use `Itertools` trait or free functions instead 416 - `itertools::size_hint` is now private 417 - Behaviour changes: 418 - `format` and `format_with` helpers now panic if you try to format them more than once. 419 - `repeat_call` is not double ended anymore 420 - New features: 421 - tuple flattening iterator is constructible with `cons_tuples` 422 - itertools reexports `Either` from the `either` crate. `Either<L, R>` is an iterator when `L, R` are. 423 - `MinMaxResult` now implements `Copy` and `Clone` 424 - `tuple_combinations` supports 1-4 tuples of combinations (previously just 2) 425## 0.4.19 426 - Add `.minmax_by()` 427 - Add `itertools::free::cloned` 428 - Add `itertools::free::rciter` 429 - Improve `.step(n)` slightly to take advantage of specialized Fuse better. 430## 0.4.18 431 - Only changes related to the "unstable" crate feature. This feature is more or less deprecated. 432 - Use deprecated warnings when unstable is enabled. `.enumerate_from()` will be removed imminently since it's using a deprecated libstd trait. 433## 0.4.17 434 - Fix bug in `.kmerge()` that caused it to often produce the wrong order #134 435## 0.4.16 436 - Improve precision of the `interleave_shortest` adaptor's size hint (it is now computed exactly when possible). 437## 0.4.15 438 - 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. 439## 0.4.14 440 - Workaround an upstream regression in a Rust nightly build that broke compilation of of `itertools::free::{interleave, merge}` 441## 0.4.13 442 - Add `.minmax()` and `.minmax_by_key()`, iterator methods for finding both minimum and maximum in one scan. 443 - Add `.format_default()`, a simpler version of `.format()` (lazy formatting for iterators). 444## 0.4.12 445 - Add `.zip_eq()`, an adaptor like `.zip()` except it ensures iterators of inequal length don't pass silently (instead it panics). 446 - Add `.fold_while()`, an iterator method that is a fold that can short-circuit. 447 - Add `.partition_map()`, an iterator method that can separate elements into two collections. 448## 0.4.11 449 - Add `.get()` for `Stride{,Mut}` and `.get_mut()` for `StrideMut` 450## 0.4.10 451 - Improve performance of `.kmerge()` 452## 0.4.9 453 - Add k-ary merge adaptor `.kmerge()` 454 - Fix a bug in `.islice()` with ranges `a..b` where a `> b`. 455## 0.4.8 456 - Implement `Clone`, `Debug` for `Linspace` 457## 0.4.7 458 - Add function `diff_with()` that compares two iterators 459 - Add `.combinations_n()`, an n-ary combinations iterator 460 - Add methods `PutBack::with_value` and `PutBack::into_parts`. 461## 0.4.6 462 - Add method `.sorted()` 463 - Add module `itertools::free` with free function variants of common iterator adaptors and methods. For example `enumerate(iterable)`, `rev(iterable)`, and so on. 464## 0.4.5 465 - Add `.flatten()` 466## 0.4.4 467 - Allow composing `ZipSlices` with itself 468## 0.4.3 469 - Write `iproduct!()` as a single expression; this allows temporary values in its arguments. 470## 0.4.2 471 - Add `.fold_options()` 472 - Require Rust 1.1 or later 473## 0.4.1 474 - Update `.dropping()` to take advantage of `.nth()` 475## 0.4.0 476 - `.merge()`, `.unique()` and `.dedup()` now perform better due to not using function pointers 477 - Add free functions `enumerate()` and `rev()` 478 - Breaking changes: 479 - Return types of `.merge()` and `.merge_by()` renamed and changed 480 - Method `Merge::new` removed 481 - `.merge_by()` now takes a closure that returns bool. 482 - Return type of `.dedup()` changed 483 - Return type of `.mend_slices()` changed 484 - Return type of `.unique()` changed 485 - Removed function `times()`, struct `Times`: use a range instead 486 - Removed deprecated macro `icompr!()` 487 - Removed deprecated `FnMap` and method `.fn_map()`: use `.map_fn()` 488 - `.interleave_shortest()` is no longer guaranteed to act like fused 489## 0.3.25 490 - Rename `.sort_by()` to `.sorted_by()`. Old name is deprecated. 491 - Fix well-formedness warnings from RFC 1214, no user visible impact 492## 0.3.24 493 - Improve performance of `.merge()`'s ordering function slightly 494## 0.3.23 495 - Added `.chunks()`, similar to (and based on) `.group_by_lazy()`. 496 - Tweak linspace to match numpy.linspace and make it double ended. 497## 0.3.22 498 - Added `ZipSlices`, a fast zip for slices 499## 0.3.21 500 - Remove `Debug` impl for `Format`, it will have different use later 501## 0.3.20 502 - Optimize `.group_by_lazy()` 503## 0.3.19 504 - Added `.group_by_lazy()`, a possibly nonallocating group by 505 - Added `.format()`, a nonallocating formatting helper for iterators 506 - Remove uses of `RandomAccessIterator` since it has been deprecated in Rust. 507## 0.3.17 508 - Added (adopted) `Unfold` from Rust 509## 0.3.16 510 - Added adaptors `.unique()`, `.unique_by()` 511## 0.3.15 512 - Added method `.sort_by()` 513## 0.3.14 514 - Added adaptor `.while_some()` 515## 0.3.13 516 - Added adaptor `.interleave_shortest()` 517 - Added adaptor `.pad_using()` 518## 0.3.11 519 - Added `assert_equal` function 520## 0.3.10 521 - Bugfix `.combinations()` `size_hint`. 522## 0.3.8 523 - Added source `RepeatCall` 524## 0.3.7 525 - Added adaptor `PutBackN` 526 - Added adaptor `.combinations()` 527## 0.3.6 528 - Added `itertools::partition`, partition a sequence in place based on a predicate. 529 - Deprecate `icompr!()` with no replacement. 530## 0.3.5 531 - `.map_fn()` replaces deprecated `.fn_map()`. 532## 0.3.4 533 - `.take_while_ref()` *by-ref adaptor* 534 - `.coalesce()` *adaptor* 535 - `.mend_slices()` *adaptor* 536## 0.3.3 537 - `.dropping_back()` *method* 538 - `.fold1()` *method* 539 - `.is_empty_hint()` *method* 540