Add to vector as hashmap value

How to add a hash map value to a vector?

use std::collections::HashMap; fn main() { let mut dict = HashMap::new(); let mut prefix = ["", ""]; let lorem = "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eum debitis earum quidem dolorem quos consequatur perspiciatis architecto! Reiciendis rem est blanditiis fugiat quidem similique suscipit soluta, ab veniam, laborum numquam. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eum debitis earum quidem dolorem quos consequatur perspiciatis architecto! Reiciendis rem est blanditiis fugiat quidem similique suscipit soluta, ab veniam, laborum numquam."; for token in lorem.split_whitespace() { if prefix[0] != "" { let key = prefix.join(" "); if !dict.contains_key(&key) { dict.insert(key, vec![token]); } else { let v = dict.get(&key); v.push(token); // does not actually return a vector } } prefix[0] = prefix[1]; prefix[1] = token; } } 

The problem is the line let v = dict.get(&key); Usually I expect that I can click on the vector, but it seems to return some kind of collection, and I'm not sure how to add it.

+5
source share
1 answer

Idiomatic solution

The idiomatic solution to your problem would be to use entry , as shown below:

 for token in lorem.split_whitespace() { if prefix[0] != "" { let key = prefix.join(" "); match dict.entry(key) { Entry::Vacant(e) => { e.insert(vec![token]); }, Entry::Occupied(mut e) => { e.get_mut().push(token); } } } prefix[0] = prefix[1]; prefix[1] = token; } 

If the key does not exist, you will get a free entry that you can use to insert the new value. If it exists, you will get a busy record that you can use to change the current value. If you want to know more, check out the documentation .

Alternative solution suggested by Huon in the comments

This is even shorter and seems better to me as soon as you understand what is going on:

 for token in lorem.split_whitespace() { if prefix[0] != "" { let key = prefix.join(" "); dict.entry(key).or_insert(Vec::new()).push(token); } prefix[0] = prefix[1]; prefix[1] = token; } 

Why your code is not working

get returns Option<&Vec<&str>> . You will need to get Vec out of the option, but even then you cannot mutate it, because it is a shared link. You can use get_mut in combination with unwrap , as shown below (however this is considered bad style. You really should use a notation):

 for token in lorem.split_whitespace() { if prefix[0] != "" { let key = prefix.join(" "); if !dict.contains_key(&key) { dict.insert(key, vec![token]); } else { let v = dict.get_mut(&key).unwrap(); v.push(token); } } prefix[0] = prefix[1]; prefix[1] = token; } 
+10
source

Source: https://habr.com/ru/post/1234147/


All Articles