按键对HashMap数据进行排序

时间:2020-01-18 09:58:37

标签: rust

交叉引用Rust forum时,我正在生成一个HashMap,如下面的playground /下面的代码所示。 如何基于map对生成的结果keys进行排序,就我而言,如何基于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);
    }

}

1 个答案:

答案 0 :(得分:3)

itertools crate扩展了标准迭代器,以便可以对其进行排序:

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);
    }
}

或者,您可以使用BTreeMap,它本身就是一个排序的地图:

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);
    }
}