在 HashMap 中使用 char 作为 &str

Use char as &str in HashMap

我想创建一个 HashMap 来映射单词 - Vec&str - 以及这些单词的字母。比如vec!["ab", "b", "abc"]会被转换成下面的HashMap

{
    // Letters are keys, words which contain the keys are values
    "a" => ["ab", "abc"],
    "b" => ["ab", "bc", "abc"],
    "c" => ["bc", "abc"],
    // Words are keys, letters which are in the words are values
    "ab" => ["a", "b"],
    "abc" => ["a", "b", "c"],
}

我试过这个代码 [playground]:

let words = vec!["ab", "bc", "abc"];
let mut map: HashMap<&str, Vec<&str>> = HashMap::new();
for word in words.iter() {
    for letter in word.chars() {
        map.entry(letter).or_default().push(word);
        map.entry(word).or_default().push(letter);
    }
}

但是有一个问题:letter 是类型 char 但我需要一个 &str 因为 map 只接受 &str 作为键。我还尝试将 letter 转换为 &str:

for word in words.iter() {
    for letter in word.chars() {
        let letter = letter.to_string()
        // no changes

但是此代码创建了一个新的 String,它的生命周期比 map 的生命周期短。换句话说,letter 在嵌套的 for 循环之后被丢弃,但是我得到了编译器错误。

如何在 HashMap 中使用仅接受 &str 作为键的 char

我会把地图分成两部分:

  • 一个是char -> Vec<&str>。它将字母映射到单词列表。
  • 第二个应该是 &str -> Vec<char>,但我不知道你是否真的需要它:为什么不直接遍历 &strchars直接?

    存储 Vec<char> 本质上只会使您使用的内存量增加一倍,除非 Vec<char> 例如按特定顺序排序(可能需要也可能不需要)。

如果你真的想把它们放在一张地图里,我觉得HashMap<String, Vec<String>>.

会更容易

问题似乎是 chars 给了你一个接一个 char,但你真正想要的是一个接一个 &str,其中每个 &str 实际上包含单个字符。我在 &str 的文档中没有找到类似的东西,但也许某处有类似这样的迭代。

您可以使用 matches:

解决它
let words = vec!["ab", "bc", "abc"];
let mut map: HashMap<&str, Vec<&str>> = HashMap::new();
for word in words.iter() {
    for letter in word.matches(|_| true) { // iterates over &str's that encompass one single character
        map.entry(letter).or_default().push(word);
        map.entry(word).or_default().push(letter);
    }
}