I am trying to convert this line from ruby to rust.
ec2.keys.sort.each do |type|
ec2 is a HashMap with a string for its key and value as a vector of type string, and I couldn't find a sort function. Is there anything similar in rust that could allow me to sort?
Thanks for your time and help.
As far as I understand your question, you’re having a HashMap<String, Vec<String>>, well… the type of the values doesn’t really matter, so let’s say ec2: HashMap<String, V>. As far as I understand the ruby docs, .keys creates an “Array” (similar to Rust’s Vec AFAICT). Then .sort sorts it (creating a new copy), and .each is a foreach loop.
In Rust, HashMap::keys is returning an Iterator, those don’t directly support sorting. But we can – like the Ruby code does – get a Vec, too, by using .collect() on the iterator. Vecs can be sorted, the .sort() method operates in-place, modifying the Vec, but that’s fine since we don’t need the unsorted vector of keys anyway (so compared to Ruby we can save some copying AFAICT). But it does mean that we need to assign the intermediate result to a mutable variable, so the code becomes a bit more lengthy.
Also, in this use case we don’t need stable sorting, so we can use .sort_unstable() which needs less memory and is slightly more efficient.
let mut ec2_keys: Vec<_> = ec2.keys().collect();
ec2_keys.sort_unstable();
for typ in ec2_keys {
// do stuff here
}
Of course you could also use .for_each instead of a for loop
let mut ec2_keys: Vec<_> = ec2.keys().collect();
ec2_keys.sort_unstable();
ec2_keys.into_iter().for_each(|typ| {
// do stuff here
});
If you’re needing to create such a sorted list of keys often, you could consider using BTreeMap instead of HashMap. A BTreeMap always has keys already sorted in the first place, so with a BTreeMap, you could just do for typ in ec2.keys() { … } or ec2.keys().for_each(|typ| …);
For convenience, the crate itertools offers a method that combines these steps of collect()ing into a Vec and then sorting (and even turning the result back into an iterator). So if you add the dependency and import itertools::Itertools, you can do