如何按插入顺序对地图进行排序?

时间:2015-05-14 17:01:51

标签: rust

我尝试过使用HashMapBTreeMap,但都没有效果:

use std::collections::{BTreeMap, HashMap};

fn main() {
    let mut btreemap = BTreeMap::new();
    println!("BTreeMap");
    btreemap.insert("Z", "1");
    btreemap.insert("T", "2");
    btreemap.insert("R", "3");
    btreemap.insert("P", "4");
    btreemap.insert("K", "5");
    btreemap.insert("W", "6");
    btreemap.insert("G", "7");
    btreemap.insert("C", "8");
    btreemap.insert("A", "9");
    btreemap.insert("D", "0");
    for (key, value) in btreemap {
        println!("{} {}", key, value);
    }
    println!("Hash Map");
    let mut hashmap = HashMap::new();
    hashmap.insert("Z", "1");
    hashmap.insert("T", "2");
    hashmap.insert("R", "3");
    hashmap.insert("P", "4");
    hashmap.insert("K", "5");
    hashmap.insert("W", "6");
    hashmap.insert("G", "7");
    hashmap.insert("C", "8");
    hashmap.insert("A", "9");
    hashmap.insert("D", "0");
    for (key, value) in hashmap {
        println!("{} {}", key, value);
    }
}

当我通过Rust playground运行时,我得到的结果没有按插入顺序排序; BTreeMap似乎按字母顺序排列(打印A C D G K P R T W Z以及数字),HashMap似乎是随机排序的(打印Z A C D R P T G WK)。

我查看了Rust标准库文档,但没有看到任何其他地图。

3 个答案:

答案 0 :(得分:3)

默认集合不跟踪插入顺序。如果您希望按此排序,则需要找到 跟踪它的其他集合,或者自己跟踪它。

答案 1 :(得分:3)

关联容器(将键映射到值的容器)通常使用两种策略之一来有效地查找键:

  • 他们根据一些比较操作对键进行排序
  • 或者根据某些散列操作对键进行散列

在这里,您有两个原型:BTree对键进行排序,HashMap对它们进行哈希处理。

如果希望跟踪插入顺序,那么关联容器是容器的错误选择,您希望的是序列容器,例如std::vec::Vec:总是推送最后的项目,您可以按插入顺序迭代它们。

注意:我建议编写一个包装器,以防止在其他地方插入不需要的内容。

另一方面,如果你想要一个跟踪插入顺序的关联容器,那么就我所知,你所要求的内容在Rust中还不存在。

在C ++中,首选解决方案名为Boost.MultiIndex,它允许您创建一个容器,您可以通过多种不同方式进行查询;它是一个相当复杂的软件,如果您浏览它的源代码,您可以看到自己。它可能会及时到达Rust,但是如果你现在需要什么东西,你将不得不亲自动手推出自己的解决方案。你可以使用Boost代码作为精益,但从经验来看,它很难阅读/理解。

答案 2 :(得分:2)

没有一个标准库集合保持一致的顺序。您可以改为使用 indexmap 板条箱中的 IndexMap,只要您不调用 remove,它就会保留插入顺序。

use indexmap::indexmap;

let map = indexmap! {
    "Z" => 1,
    "T" => 2,
    "R" => 3,
    "P" => 4,
    "K" => 5,
    "W" => 6,
};
    
for (k, v) in map {
    println!("{}: {}", k, v);
}

// Z: 1
// T: 2
// R: 3
// P: 4
// K: 5
// W: 6

它通过存储一个哈希表来实现这一点,其中键值对的迭代顺序与键的哈希值无关。这意味着查找可能比标准HashMap,但迭代和删除非常