How does one append to a vector that is a hashmap value?
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);
Normally I would expect to be able to push onto the vector, but it seems to be returning some kind of collection, which I'm not sure on how to append to.
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 doesn't exist, you will get a vacant entry that you can use to insert a new value. If it does exist, you will get an occupied entry that you can use to modify the current value. If you want to know more, check out the documentation.
This one is even shorter and seems better to me once you grasp 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;
}
get
returns an Option<&Vec<&str>>
. You would need to take the Vec
out of the option, but even in that case you cannot mutate it because it is a shared reference. You can use get_mut
in combination with unwrap
as shown below (however, this is considered bad style. You should really use entry):
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With