How to find min of a vector without Ord?

Viewed 261

I have a vector of RTSPUrl and I want to find the smallest item.

struct RTSPUrl { /* fields omitted */ }

fn main() {
    let rtsp_urls = std::vec::Vec::<RTSPUrl>::new();
    let minimum_element = rtsp_urls.iter().min();
}

However the compiler complains that RTSPUrl should implement Ord.

error[E0277]: the trait bound `RTSPUrl: std::cmp::Ord` is not satisfied
 --> src/main.rs:5:44
  |
5 |     let minimum_element = rtsp_urls.iter().min();
  |                                            ^^^ the trait `std::cmp::Ord` is not implemented for `RTSPUrl`
  |
  = note: required because of the requirements on the impl of `std::cmp::Ord` for `&RTSPUrl`

But this type isn't from my crate as it's generated by protobuf. Is there any other thing I can do?

2 Answers

You can use min_by and implement the ordering yourself:

let minimum_element = rtsp_urls.iter().min_by(|a, b| {
    // return an Ordering based on a and b
    Ordering::Equal
});

Or, if you're just ordering by some property of RTSPUrl that does implement Ord, you can use min_by_key:

let minimum_element = rtsp_urls.iter().min_by_key(|url| {
    // return something that implements Ord based on url
    url.something()
});

You didn't specify what RTSPUrl looks like or how you would want it ordered by, but one of these options should work. Link to playground.

The same pattern (*_by() and *_by_key()) is used elsewhere like max or slice.sort.

You can use Iterator::min_by and implement your own comparison, based on the contents of RTSPUrl:

let minimum_element = rtsp_urls.iter().min_by(|a, b| ...)

Your function should return an Ordering, I believe.

Related