How to get abs largest value of Vec<f32>?

Hi All,

I would like to know how to do a abs max in Rust and return the value with the sign.

fn main() {
    let ts: Vec<f32> = vec![10.0, 20.0, -30.0];
    let abs_max = ts.iter().fold(f32::NAN, |a, &b| (a.abs()).max(b.abs()));
    println!("{}", abs_max);
}

I want the result to be -30.0 in this case. But I am getting 30.0. Can the experts here help me to get an performance optimised snippet?
Also, assume there wont be any NAN in my ts.

This is a simple example. But what I need ultimately is the abs mean of the vec but the sign should be from the abs max..

let abs_max = -30.0
let abs_max_sign = abs_max.signum();
let abs_mean = YY;
let signed_abs_mean = YY * abs_max_sign;
return signed_abs_mean;

try using Iterator::max_by

fn main() {
    let ts: Vec<f32> = vec![10.0, 20.0, -30.0];
    let abs_max = ts
        .iter()
        .max_by(|x, y| x.abs().partial_cmp(&y.abs()).unwrap())
        .unwrap();
    println!("{}", abs_max);
}

Edit: added ordered_float dependency due to the f32 is not Ord

Or max_by_key

use ordered_float::NotNaN;
fn main() {
    let ts: Vec<f32> = vec![10.0, 20.0, -30.0];
    let abs_max = ts
        .iter()
        .max_by_key(|x| NotNaN::new(x.abs()).unwrap())
        .unwrap();
    println!("{}", abs_max);
}

Thanks!.
Is it possible to check it there are more than 2 elements? Because it fails when I have one element in my vec. Is there any better alternative than using if condition

I am not sure what you mean. The code i posted works just fine for only a single item.

Because it fails when I have one element in my vec.

@raggy's code works when there is only one element.

If you want to reject single-element vec, you can do like this:

fn main() {
    let ts: Vec<f32> = vec![10.0];
    let abs_max = ts
        .iter()
        .max_by(|x, y| x.abs().partial_cmp(&y.abs()).unwrap())
        .filter(|_| ts.len() >= 2)
        .expect("Less than two elements");
    println!("{}", abs_max);
}

Use Option::filter to the Option value returned by max_by().

(This might be some kind of abuse, but works for this case ;-))

1 Like

Thanks. I think when we have single element, the abs_max should be that one element. Isn't it? Currently I am using match for that

Nevermind it works. For some reason I thought It is not working

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.