简体   繁体   English

在 Rust 中,如何从 HashMap 的键创建 HashSet?

[英]In Rust, how do I create a HashSet from the keys of a HashMap?

I have two HashMap s and want to compute the intersection of the keys.我有两个HashMap并且想要计算键的交集。 Is it possible to construct a HashSet out of whatever HashMap::keys() returns?是否可以从HashMap::keys()返回的任何内容中构造一个HashSet For example:例如:

use std::collections::{HashSet, HashMap};

fn main() {
    let mut map1: HashMap<i64, i64> = HashMap::new();
    let mut map2: HashMap<i64, i64> = HashMap::new();

    // Add some values into the HashMaps for demonstration
    map1.insert(1, 10);
    map1.insert(5, 50);
    map2.insert(3, 30);
    map2.insert(5, 50);

    let set1: HashSet<i64> = HashSet::from(map1.keys());  // How to do this?
    let set2: HashSet<i64> = HashSet::from(map2.keys());  // How to do this?

    let set3 = set1.intersection(&set2); // What I'm looking to accomplish
    // set3 should contain [5], as this is the one key shared by the two HashMaps
}

The simple solution简单的解决方案

Your code only needs a few tweaks to actually compile ( see Playground ):您的代码只需要进行一些调整即可实际编译( 请参阅 Playground ):

use std::collections::{HashSet, HashMap};

fn main() {
    let mut map1 = HashMap::new();
    let mut map2 = HashMap::new();

    // Add some values into the HashMaps for demonstration
    map1.insert(1, 10);
    map1.insert(5, 50);
    map2.insert(3, 30);
    map2.insert(5, 50);

    let set1: HashSet<i64> = map1.keys().cloned().collect();
    let set2: HashSet<i64> = map2.keys().cloned().collect();

    let set3 = set1.intersection(&set2);
    println!("{:?}", set3);
}

In particular, note map1.keys().cloned().collect() :特别注意map1.keys().cloned().collect()

  • HashMap<K, V>::keys() returns an Iterator<Item = &'a K> , HashMap<K, V>::keys()返回一个Iterator<Item = &'a K>
  • .cloned() transforms that to an Iterator<Item = K> , .cloned()将其转换为Iterator<Item = K>
  • .collect() builds a collection from that, since HashSet implements the FromIterator trait. .collect()构建一个集合,因为HashSet实现了FromIterator特性。

However, this is not very efficient:但是,这不是很有效:

  • Complexity wise: O(map1.size() + map2.size()) .复杂性: O(map1.size() + map2.size())
  • Memory wise: potentially large allocations.内存明智:潜在的大分配。

The efficient solution高效的解决方案

Implement intersection directly on the keys of HashMap .直接在HashMap的键上实现intersection

You just need to collect into the HashSet :你只需要收集到HashSet

let set1: HashSet<i64> = map1.keys().copied().collect(); 
let set2: HashSet<i64> = map2.keys().copied().collect();

Using copied() will dereference the keys and copy them, since you want a HashSet<i64> not a HashSet<&i64>使用 Copy copied()将取消引用键并复制它们,因为您需要HashSet<i64>而不是HashSet<&i64>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM