Calculate mean, median, and mode in Rust I'm learning Rust using The Rust Programming Language. I'm trying the assignment at the end of chapter 8 — Hash Maps.

The task is:


  Given a list of integers, use a vector and return the mean (average), median (when sorted, the value in the middle position), and mode (the value that occurs most often; a hash map will be helpful here) of the list.


The average value and the median were very easy for me, but I struggle solving the last part of the task. I do have a working solution (see below), but I'm sure there must be some more elegant and readable way (using the standard library?) for this.

use std::collections::HashMap;
fn main() {
  let  mut numbers = vec![42, 1, 36, 34, 76, 378, 43, 1, 43, 54, 2, 3, 43];

  let avg: f32;
  let median: i32;
  let mode: i32;

  { // calculate average
      let mut sum: i32 = 0;
      for x in &amp;numbers {
          sum = sum + x;
      }

      avg = sum as f32 / numbers.len() as f32;
  }

  { // calculate median
      numbers.sort();
      let mid = numbers.len() / 2;

      median = numbers[mid];
  }

  { // calculate mode
      // new HashMap
      let mut times = HashMap::new();

      // count
      for x in &amp;numbers {
          let cnt = times.entry(*x as usize).or_insert(0);
          *cnt += 1;
      }

      let mut best: (i32, i32) = (*times.iter().nth(0).expect("Fatal.").0 as i32, *times.iter().nth(0).expect("Fatal.").1 as i32);

      for x in times.iter() {
          if *x.1 &gt; best.1 {
              best = (*x.0 as i32, *x.1);
          }
      }
      mode = best.0;
  }

  println!("AVERAGE: {}", avg);
  println!("MEDIAN: {}", median);
  println!("MODE: {}", mode)

}
Learn to love rustfmt. For example, the Rust standard is 4-space indents. 
Learn to love Clippy, which can show you the more idiomatic way to iterate over a collection:

warning: it is more idiomatic to loop over references to containers instead of using explicit iteration methods
  --&gt; src/main.rs:43:18
   |
43 |         for x in times.iter() {
   |                  ^^^^^^^^^^^^ help: to write this more concisely, try: `&amp;times`
   |
   = note: #[warn(explicit_iter_loop)] on by default
   = help: for further information visit https://github.com/Manishearth/rust-clippy/wiki#explicit_iter_loop

There's no reason to declare your variables early in the function. That's the kind of thing you would do in very old C or JavaScript and isn't required in modern languages. Declare them as late as possible.
Extract methods for each of the operations you'd like to perform. This allows you to remove the artificial blocks inside the main function and makes the comments into code identifiers. This removes the need for the variables in the main function at all.
There's no need to use a Vec as you never add or remove items from the list. A plain array will suffice.
As mentioned in the comments, Iterator::sum already exists. If it didn't, you could use something like Iterator::fold.
Your implementation of median is incorrect. When there are an even number of values, the median is defined as the average of the two middle values. I've not changed your code for this because doing so would require changing the type of median and I'm not sure how you'd prefer to do so.
There's no need to cast the value to usize when counting the number of occurrences; storing the i32 in the HashMap makes more sense.
You can dereference the number using &amp;value in the for loop binding.
Once you have built your mapping of occurrences, you can iterate over it, taking the maximum value with Iterator::max_by_key, throw away the count using Iterator::map, then have a single expect call.
Use a better error message than "Fatal" - describe what the problem was.
Don't use nth(0) - that's just .next()


use std::collections::HashMap;

fn average(numbers: &amp;[i32]) -&gt; f32 {
    numbers.iter().sum::&lt;i32&gt;() as f32 / numbers.len() as f32
}

fn median(numbers: &amp;mut [i32]) -&gt; i32 {
    numbers.sort();
    let mid = numbers.len() / 2;
    numbers[mid]
}

fn mode(numbers: &amp;[i32]) -&gt; i32 {
    let mut occurrences = HashMap::new();

    for &amp;value in numbers {
        *occurrences.entry(value).or_insert(0) += 1;
    }

    occurrences
        .into_iter()
        .max_by_key(|&amp;(_, count)| count)
        .map(|(val, _)| val)
        .expect("Cannot compute the mode of zero numbers")
}

fn main() {
    let mut numbers = [42, 1, 36, 34, 76, 378, 43, 1, 43, 54, 2, 3, 43];

    println!("AVERAGE: {}", average(&amp;numbers));
    println!("MEDIAN: {}", median(&amp;mut numbers));
    println!("MODE: {}", mode(&amp;numbers));
}


A clever one-pass solution for mode is also possible:

fn mode(numbers: &amp;[i32]) -&gt; Option&lt;i32&gt; {
    let mut counts = HashMap::new();

    numbers.iter().copied().max_by_key(|&amp;n| {
        let count = counts.entry(n).or_insert(0);
        *count += 1;
        *count
    })
}