Skip to content

Commit

Permalink
Merge #575
Browse files Browse the repository at this point in the history
575: Add `sorted_by_cached_key` to `Itertools` trait r=jswrenn a=density

Fixes #424.

This function is a wrapper around `slice::sort_by_cached_key`.

Added tests similar to those for `sorted_by_key`. New code is formatted using `rustfmt`.

Co-authored-by: Justin Prieto <justin@prieto.nyc>
  • Loading branch information
bors[bot] and density committed Oct 13, 2021
2 parents ed55a5f + a1510e7 commit 3307e4d
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/lib.rs
Expand Up @@ -2668,6 +2668,43 @@ pub trait Itertools : Iterator {
v.into_iter()
}

/// Sort all iterator elements into a new iterator in ascending order. The key function is
/// called exactly once per key.
///
/// **Note:** This consumes the entire iterator, uses the
/// [`slice::sort_by_cached_key`] method and returns the result as a new
/// iterator that owns its elements.
///
/// The sorted iterator, if directly collected to a `Vec`, is converted
/// without any extra copying or allocation cost.
///
/// ```
/// use itertools::Itertools;
///
/// // sort people in descending order by age
/// let people = vec![("Jane", 20), ("John", 18), ("Jill", 30), ("Jack", 27)];
///
/// let oldest_people_first = people
/// .into_iter()
/// .sorted_by_cached_key(|x| -x.1)
/// .map(|(person, _age)| person);
///
/// itertools::assert_equal(oldest_people_first,
/// vec!["Jill", "Jack", "Jane", "John"]);
/// ```
/// ```
#[cfg(feature = "use_alloc")]
fn sorted_by_cached_key<K, F>(self, f: F) -> VecIntoIter<Self::Item>
where
Self: Sized,
K: Ord,
F: FnMut(&Self::Item) -> K,
{
let mut v = Vec::from_iter(self);
v.sort_by_cached_key(f);
v.into_iter()
}

/// Sort the k smallest elements into a new iterator, in ascending order.
///
/// **Note:** This consumes the entire iterator, and returns the result
Expand Down
24 changes: 24 additions & 0 deletions tests/test_std.rs
Expand Up @@ -510,6 +510,30 @@ fn sorted_by_key() {
it::assert_equal(v, vec![4, 3, 2, 1, 0]);
}

#[test]
fn sorted_by_cached_key() {
// Track calls to key function
let mut ncalls = 0;

let sorted = [3, 4, 1, 2].iter().cloned().sorted_by_cached_key(|&x| {
ncalls += 1;
x.to_string()
});
it::assert_equal(sorted, vec![1, 2, 3, 4]);
// Check key function called once per element
assert_eq!(ncalls, 4);

let mut ncalls = 0;

let sorted = (0..5).sorted_by_cached_key(|&x| {
ncalls += 1;
-x
});
it::assert_equal(sorted, vec![4, 3, 2, 1, 0]);
// Check key function called once per element
assert_eq!(ncalls, 5);
}

#[test]
fn test_multipeek() {
let nums = vec![1u8,2,3,4,5];
Expand Down

0 comments on commit 3307e4d

Please sign in to comment.