在Rust中检查两个HashMap是否具有相同的键集

Jem*_*ake 1 iterator equality rust

假设我有两个HashMaps(或任何具有映射到其他键的键的映射结构)map1和map2,并且我想确保它们具有相同的键集。需要注意的是,钥匙都在地图同一类型,但不会

我最初的尝试只是:

map1.keys().eq(map2.keys())
Run Code Online (Sandbox Code Playgroud)

并且,尽管这是一次成功,但迭代器的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()
}
Run Code Online (Sandbox Code Playgroud)

Rust初学者注意:实际上,我的第一次尝试是知道映射中的键是String类型的,所以我的函数签名是:

fn keys_match<T,U>(map1:&HashMap<String,T>, map2:&HashMap<String,U>) -> bool
Run Code Online (Sandbox Code Playgroud)

直到我意识到甚至可以通过要求通用键类型具有Eq和Hash特征来通用化通用键类型

问题:在Rust中还有更简洁的方法吗?

Luk*_*odt 6

在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))
}
Run Code Online (Sandbox Code Playgroud)

游乐场

此代码对您的代码进行了三处改进:

  • 使用Iterator::all会大大缩短代码。
  • 使用HashMap::contains_key优于检查的结果HashMap::get
  • 首先检查长度,因为这是一种便宜的测试,应首先进行。

  • @TeymourAldridge 应该没有区别。如果“all”中的闭包返回“false”,它也不会进一步尝试并立即停止。“all”和“any”实际上只是彼此的倒置版本。 (2认同)