如何按插入顺序对地图进行排序?
How do I sort a map by order of insertion?
我已经尝试使用 HashMap
和 BTreeMap
来解决这个问题,但都没有用:
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 标准库文档,没有看到任何其他映射。
默认集合不跟踪插入顺序。如果您希望按此排序,您需要找到 追踪它的不同合集,或者您自己追踪它。
关联容器(将键映射到值的容器)通常使用以下两种策略之一来高效地查找键:
- 他们要么根据一些比较操作对键进行排序
- 或者他们根据一些散列操作散列密钥
在这里,您有两个原型:BTree
对键进行排序,HashMap
对它们进行哈希处理。
如果您只是希望跟踪插入顺序,那么关联容器是容器的错误选择,您想要的是序列容器,例如std::vec::Vec
: 始终将项目推到最后,您可以按照插入的顺序迭代它们。
注意:我建议编写一个包装器以防止在其他任何地方插入不需要的内容。
如果,另一方面,你想要一个关联容器也跟踪插入顺序,那么你所要求的在 Rust 中还不存在我知道。
在 C++ 中,首选解决方案称为 Boost.MultiIndex,它允许您创建一个可以通过多种不同方式查询的容器;这是一个相当复杂的软件,如果您浏览它的源代码,您就会看到自己的身影。它可能会及时出现在 Rust 中,但如果你现在需要某些东西,我担心你将不得不手动推出你自己的解决方案;您可以将 Boost 代码用作精益求精,尽管根据经验可能很难 read/understand.
None 的标准库集合保持一致的顺序。您可以改用 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
它通过存储散列 table 来实现这一点,其中键值对的迭代顺序与键的散列值无关。这意味着查找可能 比标准 HashMap
慢 ,但迭代和删除非常 快。
我已经尝试使用 HashMap
和 BTreeMap
来解决这个问题,但都没有用:
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 标准库文档,没有看到任何其他映射。
默认集合不跟踪插入顺序。如果您希望按此排序,您需要找到 追踪它的不同合集,或者您自己追踪它。
关联容器(将键映射到值的容器)通常使用以下两种策略之一来高效地查找键:
- 他们要么根据一些比较操作对键进行排序
- 或者他们根据一些散列操作散列密钥
在这里,您有两个原型:BTree
对键进行排序,HashMap
对它们进行哈希处理。
如果您只是希望跟踪插入顺序,那么关联容器是容器的错误选择,您想要的是序列容器,例如std::vec::Vec
: 始终将项目推到最后,您可以按照插入的顺序迭代它们。
注意:我建议编写一个包装器以防止在其他任何地方插入不需要的内容。
如果,另一方面,你想要一个关联容器也跟踪插入顺序,那么你所要求的在 Rust 中还不存在我知道。
在 C++ 中,首选解决方案称为 Boost.MultiIndex,它允许您创建一个可以通过多种不同方式查询的容器;这是一个相当复杂的软件,如果您浏览它的源代码,您就会看到自己的身影。它可能会及时出现在 Rust 中,但如果你现在需要某些东西,我担心你将不得不手动推出你自己的解决方案;您可以将 Boost 代码用作精益求精,尽管根据经验可能很难 read/understand.
None 的标准库集合保持一致的顺序。您可以改用 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
它通过存储散列 table 来实现这一点,其中键值对的迭代顺序与键的散列值无关。这意味着查找可能 比标准 HashMap
慢 ,但迭代和删除非常 快。