70

I'm trying to display the minimum value within a vector in Rust and can't find a good way to do so.

Given a vector of i32 :

let mut v = vec![5, 6, 8, 4, 2, 7];

My goal here is to get the minimum value of that vector without having to sort it.

What is the best way to get the minimum value within a Vec<i32> in Rust ?

5 Answers 5

76
let minValue = vec.iter().min();
match minValue {
    Some(min) => println!( "Min value: {}", min ),
    None      => println!( "Vector is empty" ),
}

https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.min

fn min(self) -> Option<Self::Item>
where
    Self::Item: Ord, 

Returns the minimum element of an iterator.

If several elements are equally minimum, the first element is returned. If the iterator is empty, None is returned.

I found this Gist which has some common C#/.NET Linq operations expressed in Swift and Rust, which is handy: https://gist.github.com/leonardo-m/6e9315a57fe9caa893472c2935e9d589

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Dai, I think this is to get the max value, what about the min value ? Because in return I have Some(8) when I actually need to get only 8when I do a println!("{:#?}", maxValue); since println!("{}", maxValue); returns an error.
@octano println!("{}", maxValue.unwrap());
At least for now, doing iter.copied().min() gets significantly better codegen, it even auto vectorizes well. If you doing without copied() it is... a mess (copied() at the end doesn't help).
23
let mut v = vec![5, 6, 8, 4, 2, 7];
let minValue = *v.iter().min().unwrap();

3 Comments

Fairly new to Rust, but what does the * do here exactly? It works without it as well.
@CallumMatthews You can find the answer on this question, stackoverflow.com/questions/40531912/…
At least for now, doing iter.copied().min() gets significantly better codegen, it even auto vectorizes well. If you doing without copied() it is... a mess (copied() at the end doesn't help).
5

Hi @octano As Dai has already answered, min/max return Option<> value, so you can only match it as in example:

fn main() {
    let vec_to_check = vec![5, 6, 8, 4, 2, 7];
    let min_value = vec_to_check.iter().min();
    match min_value {
        None => println!("Min value was not found"),
        Some(i) => println!("Min Value = {}", i)
    }
}

Play ground example for Iter.min()

4 Comments

@aws_apprentice When blandger replied my answer didn't include the match part. This was just bad timing.
There are no rules on this site for duplicate answers. You're welcome to expand your answer to attract up votes, and the key is to post correct answers.
Yes, the duplicate reason is timing issue, I posted answer and Dai is updated his answer soon.
At least for now, doing iter.copied().min() gets significantly better codegen, it even auto vectorizes well. If you doing without copied() it is... a mess (copied() at the end doesn't help).
0
let max = nums.iter().max().unwrap_or(&0);

You can use unwrap_or(value) to return default value if max not found.

2 Comments

It is probably better (from performance & clarity point of view) to do .copied().unwrap_or(0).
At least for now, doing iter.copied().min() gets significantly better codegen, it even auto vectorizes well. If you doing without copied() it is... a mess (copied() at the end doesn't help).
-1

See the functions: fn min() and fn fold().

Another option, not necessarily the most efficient.

"Folding is useful whenever you have a collection of something, and want to produce a single value from it."

fn main() {
    let values: Vec<i32> = vec![5, 6, 8, 4, 2, 7];

    // The empty vector must be filtered beforehand!
    // let values: Vec<i32> = vec![]; // Not work!!!

    // Get the minimum value without being wrapped by Option<T>
    let min_value: i32 = values
        .iter()
        //.into_iter()
        //.fold(i32::MAX, i32::min);
        .fold(i32::MAX, |arg0: i32, other: &i32| i32::min(arg0, *other));

    println!("values: {values:?}");
    println!("min_value: {min_value}");

    assert_eq!(min_value, 2);
}

See Rust Playground

1 Comment

This is strictly worse than using Iterator::min().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.