假设我有两个HashMap(或者,任何键映射到其他东西的映射结构(,map1和map2,我想确保它们有一组相同的键。请注意,键在映射中是相同的类型,但值是而不是。
我最初的尝试只是:
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中有更简洁的方法吗
在Rust中有更简洁的方法吗?
fn keys_match<T: Eq + Hash, U, V>(
map1: &HashMap<T, U>,
map2: &HashMap<T, V>,
) -> bool {
map1.len() == map2.len() && map1.keys().all(|k| map2.contains_key(k))
}
(游乐场(
此代码比您的代码有三个改进:
- 使用
Iterator::all
大大缩短了代码 - 使用CCD_ 2比检查CCD_ 3的结果要好
- 这首先检查长度,因为这是一个廉价的测试,应该首先进行