I am trying to solve a problem put in The Rust Programming Language #2
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.
I decided to put the values in a simple struct and return a Result
. I want to be sure I'm using all the language features within the calculations and I want to reduce the amount of casts if possible.
use std::collections::HashMap;
/// structure to represent the values after calculating the mean,
/// median, and mode of some integers.
/// the mode Vec holds each individual mode.
#[derive(Debug)]
pub struct Calculations {
mean: f64,
median: f64,
mode: Vec<i32>,
}
/// calculates the mean, median, and mode of values.
/// returns a Result holding a Calculations or an error string
/// when given an empty slice
pub fn calculate_mmm(values: &[i32]) -> Result<Calculations, &str> {
// if input is an empty slice, return an error message
if values.is_empty() { return Err("Found empty slice") }
// add all numbers together and divide by length
let mean = values.iter().fold(0, |p, &q| p + q) as f64 / values.len() as f64;
// sort all values and return middle element or average of middle 2 elements
let median = {
let mut sorted = values.to_vec();
sorted.sort();
if sorted.len() % 2 == 0 {
(sorted[sorted.len() / 2] + sorted[(sorted.len() / 2) + 1]) as f64 / 2.0
} else {
sorted[(sorted.len() as f64 / 2.0) as usize] as f64
}
};
// holds modes
let mut mode: Vec<i32> = Vec::new();
// holds each number and the number of times it occures
let mut occurrences = HashMap::new();
for i in values {
let count = occurrences.entry(i).or_insert(0);
*count += 1;
}
// the maximum times a value occurres
let mut max_value = 0;
for &value in occurrences.values() {
if value > max_value {
max_value = value;
}
}
// find the numbers which occur the maximum number of times
for (key, value) in occurrences {
if value == max_value {
mode.push(*key);
}
}
// return all values
Ok(
Calculations { mean: mean as f64, median: median as f64, mode: mode }
)
}