Calculating median exercise feedback

I'm learning Rust through the official book and rustlings. When reading things seem to make sense but I was kind of lost trying to write code by myself. At the end of chapter 8 there are a couple of exercises and one of them is to write a function that calculates the mean. I'd appreciate any feedback on my code, as there aren't official solutions.

fn median(list: &[i32]) -> Option<f64> {
    let mut list = list.to_vec();
    if list.is_empty() {
        None
    } else if list.len() == 1 {
        Some(*list.first()? as f64)
    } else {
        list.sort();
        if list.len() % 2 == 1 {
            Some(*list.get(list.len() / 2)? as f64)
        } else {
            Some(
                ((*list.get(list.len() / 2)? as f64) + (*list.get(list.len() / 2 - 1)? as f64))
                    / 2.0,
            )
        }
    }
}

fn main() {
    let v = vec![1, 2, 6, 7, 4, 5];
    let median = median(&v);
    if let Some(num) = median {
        println!("The median is {num}")
    }
}

Good to see that you have it returning Option.

I think when the exercise was written they were expecting you to use sort like that, but these days you can get a better complexity class with https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable.

So if I were to use this, I would not sort the list and then use select_nth_unstable instead of list.get()?

get returns an option - but since you handle empty and length 1 separately indexing is safe...

    match list {
        [] => None,
        [a] => Some(*a as f64),
        _ => {
            let mut list = list.to_vec();
            list.sort_unstable();
            let mid = list.len() / 2;
            Some(if list.len() % 2 == 1 {
                list[mid] as f64
            } else {
                (list[mid] as f64 + list[mid - 1] as f64) / 2.0
            })
        }
    }
1 Like