【发布时间】:2019-10-29 21:51:54
【问题描述】:
假设我有两个 HashMap(或者,any 映射结构,其键映射到其他东西),map1 和 map2,我想确保它们具有相同的键集。请注意,keys 在地图中是相同的类型,但 values 是 not。
我最初的尝试只是:
map1.keys().eq(map2.keys())
并且,虽然这在 第一次 时起作用,但迭代器的 eq 函数(可以理解)似乎按迭代器生成的顺序比较键 ,不是通过检查第二个迭代器中任何地方的键是否存在。这一点,再加上 HashMap::keys() 产生一个迭代器,其中 键的顺序是非确定性的,这意味着即使集合(在集合中理论意义)的键是相同的。
所以,我的下一个尝试是创建一个这样做的函数:
fn keys_match<T:std::cmp::Eq + std::hash::Hash,U,V>(map1:&HashMap<T,U>, map2:&HashMap<T,V>) -> bool {
// Make sure that map1.keys() ⊆ map2.keys()
for key in map1.keys() {
match map2.get(key) {
None => return false,
Some(_) => {}
}
}
// If map1.keys() ⊆ map2.keys() and their sizes equal, then the sets are equal
map1.len() == map2.len()
}
Rust 初学者注意事项:我的第一次尝试实际上是在知道映射中的键是 String 类型的情况下,所以我的函数签名是:
fn keys_match<T,U>(map1:&HashMap<String,T>, map2:&HashMap<String,U>) -> bool
直到我意识到我什至可以通过要求它们具有 Eq 和 Hash 特征来泛化 公共键类型。
问题:在 Rust 中有更简洁的方法吗?
【问题讨论】:
-
不是一个答案,但您可能应该先测试大小,这样如果长度不同,您就不会浪费时间比较密钥。
-
很好的建议。我想我在试图限制早期返回和限制代码大小方面有点陷入困境,但你是对的,前提是 HashMap::len() 本身不会迭代键(并且取决于您的用例是否倾向于测试大小相同但不同的集合),首先测试长度是一个重要的考虑因素。