在Rust中检查两个哈希映射是否存在相同的键集

在Rust中检查两个哈希映射是否存在相同的键集,rust,iterator,equality,Rust,Iterator,Equality,假设我有两个HashMap,或者任何一个map结构,其中的键映射到另一个东西map1和map2,我想确保它们有一组相同的键。请注意,这些键在贴图中的类型相同,但值不同 我最初的尝试只是: map1.keys().eq(map2.keys()) 而且,虽然这是第一次工作,但可以理解的是,迭代器的eq函数似乎按照迭代器生成的顺序比较键,而不是通过检查第二个迭代器中是否存在键。这一点,再加上HashMap::keys生成了一个迭代器,其中键的顺序是不确定的,这意味着即使键的集合理论意义上的集合是相同

假设我有两个HashMap,或者任何一个map结构,其中的键映射到另一个东西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中实现这一点

有没有一种更简洁的方法可以在铁锈中实现这一点

键匹配 映射1:&哈希映射, map2:&哈希映射, ->布尔{ map1.len==map2.len&&map1.keys.all | k | map2.contains_keyk }

与您的代码相比,此代码有三个改进:

使用会大大缩短代码。 使用优于检查HashMap::get的结果。 这将首先检查长度,因为这是一个便宜的测试,应该首先进行。 有没有一种更简洁的方法可以在铁锈中实现这一点

键匹配 映射1:&哈希映射, map2:&哈希映射, ->布尔{ map1.len==map2.len&&map1.keys.all | k | map2.contains_keyk }

与您的代码相比,此代码有三个改进:

使用会大大缩短代码。 使用优于检查HashMap::get的结果。 这将首先检查长度,因为这是一个便宜的测试,应该首先进行。
不是答案,但是你应该先测试一下尺寸,这样如果长度不同,你就不会浪费时间比较钥匙了。很好的建议。我想我在尝试限制早期返回和限制代码大小时有点纠结,但你是对的,前提是HashMap::len本身不迭代键,并且取决于你的用例是否倾向于测试相同大小但不同的集,首先测试长度是一个重要的考虑因素。这不是答案,但是你可能应该先测试一下尺寸,这样如果长度不同,你就不会浪费时间比较键了。很好的建议。我想我在尝试限制早期返回和限制代码大小时有点纠结,但你是对的,前提是HashMap::len本身不会迭代键,这取决于你的用例是否倾向于测试相同大小但不同的集,首先测试长度是一个重要的考虑因素。我从未遇到.all函数或.any for迭代器。我现在知道如何在其他支持迭代器的语言中查找它了。@Jemenake是的,迭代器的许多方法都非常好,可以真正缩短代码。在我看来,这会让它更具可读性:mayMap1.keys.any | k |!map2.keyk的效率与On的性能最差情况相同,但最好情况要好得多。@TeymourAldridge应该没有区别。如果all中的闭包返回false,它也不会进一步尝试并立即停止。all和any实际上只是彼此的反转版本。哦,等等,当然-对不起,我的错。我从来没有遇到过.all函数和.any for迭代器。我现在知道如何在其他支持迭代器的语言中查找它了。@Jemenake是的,迭代器的许多方法都非常好,可以真正缩短代码。在我看来,这会让它更具可读性:mayMap1.keys.any | k |!map2.keyk的效率与On的性能最差情况相同,但最好情况要好得多。@TeymourAldridge应该没有区别。如果all中的闭包返回false,它也不会进一步尝试并立即停止。所有的一切都只是彼此的倒转版本。哦,等等,当然——对不起,我的错。