Higher order functions in this code?


#1

So I’m currently making my way through the Rust book, and I ran into an interesting problem asking me to write code to calculate the mode. I came up with an answer, but I was wondering if there was a way to do the same thing with more higher order functions. I’m using 2 for loops currently, doesn’t really look that efficient :slightly_smiling_face:

use std::collections::HashMap;

fn main() {
    let number_vec = vec![19, 54, 88, 42, 16, 72, 63, 77, 90, 45, 45, 90, 75, 19];
    
    let mut mode_hashmap = HashMap::new();
    for i in number_vec {
        *mode_hashmap.entry(i).or_insert(0) += 1;
    }

    let mut mode_vec = Vec::new();
    let mut max_occurrences = 0;

    for (key, value) in mode_hashmap {
        if value > max_occurrences {
            max_occurrences = value;
            mode_vec.clear();
            mode_vec.push(key);
        }
        else if value == max_occurrences {
            mode_vec.push(key);
        }
    }

    mode_vec.sort_unstable();
    println!("{:?}", mode_vec);
}

#2

A first alternative algorithm is to sort the array, and then look for the longest interval of equal items. I think you can return that as a slice if you’re allowed to sort the input in place.


#3

Hmm, how about if there’s 2 sets of numbers that have the same length?


#4

Keep a vec of the equally longest slices while you scan the sorted input? (Or just a vec of the values of the longest sequences of equal values).


#5

How would I scan the sorted input for intervals? I’m not quite sure how it’d be different to what I’m doing already with the mode_hashmap


#6

While you scan keep some state, the index of the start of the current run of equal values, the vec with the values of the runs of max length, and their length (so two usize and a Vec). You update such state and keep correct your invariants.