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; }
source share