附加到矢量作为hashmap的值

时间:2015-10-20 18:09:07

标签: 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 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);通常我希望能够推进向量,但它似乎正在返回某种类型的集合,我不确定如何追加。< / p>

1 个答案:

答案 0 :(得分:16)

惯用解决方案

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

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

如果该密钥不存在,您将获得一个可用于插入新值的空白条目。如果它确实存在,您将获得一个可用于修改当前值的已占用条目。如果您想了解更多信息,请查看documentation

Huon在评论

中提出的替代解决方案

这个更短,一旦你掌握了正在发生的事情,对我来说似乎更好:

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会返回Option<&Vec<&str>>。你需要从Vec中取出选项,但即使在这种情况下你也不能改变它,因为它是一个共享引用。您可以将get_mutunwrap结合使用,如下所示(但是,这被视为不良风格。您应该使用条目):

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