pub(crate) trait SortVecExtension: Iterator {
fn sort_vec(self) -> Vec<Self::Item>
where
Self::Item: Ord;
fn sort_desc_vec(self) -> Vec<Self::Item>
where
Self::Item: Ord;
fn sort_by_vec<F>(self, f: F) -> Vec<Self::Item>
where
F: FnMut(&Self::Item, &Self::Item) -> std::cmp::Ordering;
}
impl<I> SortVecExtension for I
where
I: Iterator,
{
fn sort_by_vec<F>(self, mut f: F) -> Vec<Self::Item>
where
F: FnMut(&Self::Item, &Self::Item) -> std::cmp::Ordering,
{
let mut iter: Vec<Self::Item> = self.collect();
iter.sort_by(|a, b| f(a, b));
iter
}
fn sort_vec(self) -> Vec<Self::Item>
where
Self::Item: Ord,
{
{
let mut vec = self.collect::<Vec<_>>();
vec.sort();
vec
}
}
fn sort_desc_vec(self) -> Vec<Self::Item>
where
Self::Item: Ord,
{
let mut vec = self.sort_vec();
vec.reverse();
vec
}
}
pub trait SortExtension: Iterator {
fn sort(self) -> std::vec::IntoIter<<Self as Iterator>::Item>
where
Self::Item: Ord,
Self: Sized,
{
self.sort_vec().into_iter()
}
fn sort_desc(self) -> std::vec::IntoIter<<Self as Iterator>::Item>
where
Self::Item: Ord,
Self: Sized,
{
self.sort_desc_vec().into_iter()
}
fn sort_by<F>(self, f: F) -> std::vec::IntoIter<<Self as Iterator>::Item>
where
F: FnMut(&Self::Item, &Self::Item) -> std::cmp::Ordering,
Self: Sized,
{
self.sort_by_vec(f).into_iter()
}
}
impl<I> SortExtension for I where I: Iterator {}
#[cfg(test)]
mod test {
use crate::prelude::*;
#[test]
fn sorting() {
let a = vec![4, 1, 3, 5, 2];
assert_eq!(a.iter().cloned().sort_vec(), vec![1, 2, 3, 4, 5]);
assert_eq!(a.iter().cloned().sort_desc_vec(), vec![5, 4, 3, 2, 1]);
assert_eq!(
a.iter().cloned().sort_by_vec(|a, b| b.cmp(a)),
vec![5, 4, 3, 2, 1]
);
}
#[test]
fn sorting_by() {
let a = vec![4., 1., 3., 5., 2.];
assert_eq!(
a.iter()
.cloned()
.sort_by_vec(|a, b| a.partial_cmp(b).unwrap()),
vec![1., 2., 3., 4., 5.]
);
assert_eq!(
a.into_iter().sort_by_vec(|a, b| b.partial_cmp(a).unwrap()),
vec![5., 4., 3., 2., 1.]
);
}
#[test]
fn readme() {
let vec = vec![3, 2, 1];
let sorted_and_filtered = vec.iter().sort().filter(|a| a > &&1).to_vec();
assert_eq!(sorted_and_filtered, vec![&2, &3]);
let mut sorted = vec.iter().collect::<Vec<_>>();
sorted.sort();
let filtered = sorted.into_iter().filter(|a| a > &&1).collect::<Vec<_>>();
assert_eq!(filtered, vec![&2, &3]);
}
}