Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Sort Vector of Structs by Chronos DateTime Field?

I have this struct

pub struct Items {
    pub symbol: String,
    pub price: f64,
    pub date: DateTime<Utc>,
}

I have a vector of these structs. I would like to sort them by date. How would I go about doing that? I tried deriving PartialEq, Ord, Eq, etc... but Rust complains about the float fields.

like image 234
Lord of Grok Avatar asked Sep 16 '25 08:09

Lord of Grok


1 Answers

The easiest way is to use one of the provided sort functions implemented for Vec like sort_by, sort_by_key, or sort_by_key_cached.

// Using sort_by
foo_items.sort_by(|a, b| a.date.cmp(&b.date));

// Using sort_by_key
foo_items.sort_by_key(|x| x.date);

// Using sort_by_key_cached (Faster if key is very large)
foo_items.sort_by_cached_key(|x| x.date);

And don't forget you always have the option to manually implement traits that are normally derived.

use std::cmp::Ordering;

impl PartialEq for Items {
    fn eq(&self, other: &Self) -> bool {
        // idk what symbol is, but use it anyway
        self.symbol == other.symbol && self.date == other.date
    }
}

impl Eq for Items {}

impl PartialOrd for Items {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.date.partial_cmp(&other.date)
    }
}

impl Ord for Items {
    fn cmp(&self, other: &Self) -> Ordering {
        self.date.cmp(&other.date)
    }
}

Edit: I just wanted to add an extra note here for anyone who is viewing this.

Firstly, these sorting functions are implemented for slices, not Vec (the example doesn't change though). When used, Vec<T>'s implementation of DerefMut is implicitly called to get a &mut [T] that implements the sorting function. This means that you can sort any data structure you can get a mutable slice of.

Second, using sort_unstable is almost always preferable to sort (there are also variants for _by, and _by_key). To quote to documentation:

Sorts the slice, but might not preserve the order of equal elements.

This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not allocate), and O(n * log(n)) worst-case.

Current implementation
The current algorithm is based on pattern-defeating quicksort by Orson Peters, which combines the fast average case of randomized quicksort with the fast worst case of heapsort, while achieving linear time on slices with certain patterns. It uses some randomization to avoid degenerate cases, but with a fixed seed to always provide deterministic behavior.

It is typically faster than stable sorting, except in a few special cases, e.g., when the slice consists of several concatenated sorted sequences.

like image 196
Locke Avatar answered Sep 18 '25 18:09

Locke



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!