Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
342 views
in Technique[技术] by (71.8m points)

string - 在HashMap中将char用作&str(Use char as &str in HashMap)

I want to create a HashMap which maps words — a Vec of &str — and letters of those words each to another.

(我想创建一个HashMap ,该映射将单词( &strVec&str这些单词的字母彼此映射。)

For example, vec!["ab", "b", "abc"] will be converted to the following HashMap

(例如, 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"],
}

I tried this code [ 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);
    }
}

but there is a problem: letter is of type char but I need a &str because map accepts only &str s as keys.

(但是有一个问题: letterchar类型,但是我需要一个&str因为map只接受&str作为键。)

I also tried to convert letter to a &str :

(我也试图将letter转换为&str :)

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

but this code creates a new String which has a smaller lifetime than map 's one.

(但是这段代码创建了一个新的String ,其寿命比map的寿命短。)

In other words, letter is dropped after the nested for loop but and I get compiler error.

(换句话说,在嵌套的for循环后删除了letter for但是出现编译器错误。)

How can I use a char in HashMap which accepts only &str s as keys?

(如何在HashMap使用仅接受&str用作键的char ?)

  ask by Oleh Misarosh translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I would separate the map into two:

(我将地图分为两部分:)

  • One is char -> Vec<&str> .

    (一个是char -> Vec<&str> 。)

    It maps letters to a list of words.

    (它将字母映射到单词列表。)

  • The second one would be &str -> Vec<char> , but I do not know if you really need it: Why not just iterate over the chars of a &str directly?

    (第二个是&str -> Vec<char> ,但是我不知道您是否真的需要它:为什么不直接迭代&strchars ?)

    Storing a Vec<char> essentially just doubles the amount of memory you use, unless the Vec<char> is eg sorted in a particular order (which may or may not be necessary).

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

If you really want to keep them in one map, I think it is easier to have a HashMap<String, Vec<String>> .

(如果您真的想将它们保留在一张地图中,我认为拥有HashMap<String, Vec<String>>更容易。)

The problem seems to be that chars gives you one char after another, but what you actually want is a &str after another, where each &str actually encompasses a single character.

(问题似乎是, chars给您一个接一个的char ,但是您真正想要的是一个&str一个接一个的字符,其中每个&str实际上都包含一个字符。)

I did not find anything like that in the docs for &str , but maybe there is something somewhere that iterates like this.

(我在&str的文档中没有找到类似的东西,但是也许在某些地方有这样的迭代。)

You could work-around it using matches :

(您可以使用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);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...