Skip to content

Commit

Permalink
Merge #494
Browse files Browse the repository at this point in the history
494: Added unstable variants of sort from std r=jswrenn a=BudiNverse

Hello! This PR adds the following methods

- `sorted_unstable`
- `sorted_unstable_by`
- `sorted_unstable_by_key`

The methods mentioned above have the same signature as the normal sorted version. Internally, all of them uses the unstable variants of sort from std.

Co-authored-by: BudiNverse <me@inve.rs>
  • Loading branch information
bors[bot] and zeon256 committed Nov 9, 2020
2 parents a2b3aef + 33efe95 commit 9958c45
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 0 deletions.
95 changes: 95 additions & 0 deletions src/lib.rs
Expand Up @@ -2187,6 +2187,101 @@ pub trait Itertools : Iterator {
.map(|first| once(first).chain(self).product())
}

/// Sort all iterator elements into a new iterator in ascending order.
///
/// **Note:** This consumes the entire iterator, uses the
/// `slice::sort_unstable()` 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 the letters of the text in ascending order
/// let text = "bdacfe";
/// itertools::assert_equal(text.chars().sorted_unstable(),
/// "abcdef".chars());
/// ```
#[cfg(feature = "use_alloc")]
fn sorted_unstable(self) -> VecIntoIter<Self::Item>
where Self: Sized,
Self::Item: Ord
{
// Use .sort_unstable() directly since it is not quite identical with
// .sort_by(Ord::cmp)
let mut v = Vec::from_iter(self);
v.sort_unstable();
v.into_iter()
}

/// Sort all iterator elements into a new iterator in ascending order.
///
/// **Note:** This consumes the entire iterator, uses the
/// `slice::sort_unstable_by()` 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_unstable_by(|a, b| Ord::cmp(&b.1, &a.1))
/// .map(|(person, _age)| person);
///
/// itertools::assert_equal(oldest_people_first,
/// vec!["Jill", "Jack", "Jane", "John"]);
/// ```
#[cfg(feature = "use_alloc")]
fn sorted_unstable_by<F>(self, cmp: F) -> VecIntoIter<Self::Item>
where Self: Sized,
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
let mut v = Vec::from_iter(self);
v.sort_unstable_by(cmp);
v.into_iter()
}

/// Sort all iterator elements into a new iterator in ascending order.
///
/// **Note:** This consumes the entire iterator, uses the
/// `slice::sort_unstable_by_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_unstable_by_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_unstable_by_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_unstable_by_key(f);
v.into_iter()
}

/// Sort all iterator elements into a new iterator in ascending order.
///
Expand Down
20 changes: 20 additions & 0 deletions tests/test_std.rs
Expand Up @@ -343,6 +343,26 @@ fn join() {
assert_eq!(none.iter().join(", "), "");
}

#[test]
fn sorted_unstable_by() {
let sc = [3, 4, 1, 2].iter().cloned().sorted_by(|&a, &b| {
a.cmp(&b)
});
it::assert_equal(sc, vec![1, 2, 3, 4]);

let v = (0..5).sorted_unstable_by(|&a, &b| a.cmp(&b).reverse());
it::assert_equal(v, vec![4, 3, 2, 1, 0]);
}

#[test]
fn sorted_unstable_by_key() {
let sc = [3, 4, 1, 2].iter().cloned().sorted_unstable_by_key(|&x| x);
it::assert_equal(sc, vec![1, 2, 3, 4]);

let v = (0..5).sorted_unstable_by_key(|&x| -x);
it::assert_equal(v, vec![4, 3, 2, 1, 0]);
}

#[test]
fn sorted_by() {
let sc = [3, 4, 1, 2].iter().cloned().sorted_by(|&a, &b| {
Expand Down

0 comments on commit 9958c45

Please sign in to comment.