Cross referencing to Rust forum, I'm generating a HashMap as in this playground / below code.
How can I sort the generated result map
based on the keys
, in my case based on Dimension, Location
:
use std::collections::HashMap;
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
struct Dimension {
item: String,
color: String,
size: String,
part_number: String
}
#[derive(Debug)]
struct Delivery {
variant: Dimension,
location: String,
quantity: i32,
}
pub fn main() {
let data = vec![
Delivery {
variant: Dimension {item: String::from("A"),
color: String::from("B"),
size: String::from("C"),
part_number: String::from("D")},
location: String::from("L"),
quantity: 10,
},
Delivery {
variant: Dimension {item: String::from("A"),
color: String::from("B"),
size: String::from("C"),
part_number: String::from("D")},
location: String::from("L2"),
quantity: 3,
},
Delivery {
variant: Dimension {item: String::from("A"),
color: String::from("B"),
size: String::from("C"),
part_number: String::from("D1")},
location: String::from("L"),
quantity: 5,
},
Delivery {
variant: Dimension {item: String::from("A"),
color: String::from("B"),
size: String::from("C"),
part_number: String::from("D")},
location: String::from("L"),
quantity: 5,
},
];
// The keys of this map will be groups
let mut map: HashMap<(Dimension, String), Delivery> = HashMap::new();
for d in data {
let record = map
.entry((d.variant.clone(), d.location.clone()))
.or_insert(Delivery {
variant: d.variant.clone(),
location: d.location.clone(),
quantity: 0,
});
record.quantity += d.quantity;
}
for (variant, delivery) in &map {
println!("{:?} has {:?}", variant, delivery.quantity);
}
}
Java HashMap does not preserve any order by default. If there is a need to sort HashMap we sort it explicitly based on the requirements. Java provides an option to sort HashMap based on keys and values.
Our task is to sort the hashmap according to values i.e. according to marks. Solution: The idea is to store the entry set in a list and sort the list on the basis of values. Then fetch values and keys from the list and put them in a new hashmap. Thus, a new hashmap is sorted according to values.
To sort the String values in the list we use a comparator. This comparator sorts the list of values alphabetically. Once, we have sorted the list, we build the HashMap based on this sorted list. HashMap entries are sorted according to String value.
The itertools
crate extends the standard iterator so that it can be sorted:
use std::collections::HashMap;
use itertools::Itertools; // itertools = "0.8"
#[derive(Debug, Eq, PartialEq, Hash, Clone, Ord, PartialOrd)]
struct Dimension {
item: String,
color: String,
size: String,
part_number: String,
}
fn main() {
// ...
for key in map.keys().sorted() {
println!("{:?} has {:?}", key, map[key].quantity);
}
}
Alternatively, you can use BTreeMap, which is a sorted map by itself:
use std::collections::BTreeMap;
#[derive(Debug, Eq, PartialEq, Hash, Clone, Ord, PartialOrd)]
struct Dimension {
item: String,
color: String,
size: String,
part_number: String
}
fn main() {
// ...
let mut map = BTreeMap::new();
for d in data {
let record = map
.entry((d.variant.clone(), d.location.clone()))
.or_insert(Delivery {
variant: d.variant.clone(),
location: d.location.clone(),
quantity: 0,
});
record.quantity += d.quantity;
}
for (variant, delivery) in &map {
println!("{:?} has {:?}", variant, delivery.quantity);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With