A few times I've had the desire to sort objects in a list or tree by a custom key/lambda, but currently that is a bit cumbersome. You have to define a new-type wrapper and impl Ord
for it. It would be nicer if the std::cmp
module had a helper for this. It already has one for std::cmp::Reverse
...
This is what I propose:
#[derive(Debug, Copy, Clone)]
pub struct OrderBy<T, F, U>
where
F: Fn(&T) -> U,
U: Ord,
{
inner: T,
by: F,
}
impl<T, F, U> PartialEq for OrderBy<T, F, U>
where
F: Fn(&T) -> U,
U: Ord,
{
fn eq(&self, other: &Self) -> bool {
(self.by)(&self.inner).eq(&(other.by)(&other.inner))
}
}
impl<T, F, U> Eq for OrderBy<T, F, U>
where
F: Fn(&T) -> U,
U: Ord,
{
}
impl<T, F, U> PartialOrd for OrderBy<T, F, U>
where
F: Fn(&T) -> U,
U: Ord,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T, F, U> Ord for OrderBy<T, F, U>
where
F: Fn(&T) -> U,
U: Ord,
{
fn cmp(&self, other: &Self) -> Ordering {
(self.by)(&self.inner).cmp(&(other.by)(&other.inner))
}
}
impl<T, F, U> OrderBy<T, F, U>
where
F: Fn(&T) -> U,
U: Ord,
{
pub fn new(inner: T, by: F) -> Self {
Self { inner, by }
}
pub fn into_inner(self) -> T {
self.inner
}
}