Rust 附加到向量作为hashmap的值

Rust 附加到向量作为hashmap的值,rust,Rust,如何附加到作为hashmap值的向量 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 consequ

如何附加到作为hashmap值的向量

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;
    }
}
问题是行
let v=dict.get(&key)通常我希望能够推送到向量上,但它似乎返回某种集合,我不确定如何附加到该集合。

惯用解决方案 解决问题的惯用方法是使用,如下所示:

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;
}
如果密钥不存在,您将获得一个空条目,可以使用它插入新值。如果它确实存在,您将获得一个已占用的条目,您可以使用该条目修改当前值。如果您想了解更多,请查看

休恩在评论中提出的替代解决方案 这一个甚至更短,而且在我看来,一旦你掌握了正在发生的事情:

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
返回一个
选项
。您需要将
Vec
从选项中去掉,但即使在这种情况下,您也不能对其进行变异,因为它是一个共享引用。您可以将
get_mut
unwrap
结合使用,如下所示(但是,这被认为是错误的样式。您应该真正使用entry):


Vec
s的
Entry
s的一个常见技巧是:
dict.Entry(key)。或_insert(Vec::new()).push(token)
。(
Vec::new()
非常便宜,只存储了三个常量,所以可以无条件计算。)太棒了!我编辑了我的答案以说明此备选方案。您可以在不需要时通过使用:
dict.entry(key.)或插入(Vec::new).推送(token)避免分配
注意,这两种情况下都没有分配,因为
Vec::new()
不分配。Rust向量仅在推送第一个元素时分配(或在未实际推送的情况下显式设置容量时分配)
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;
}