【问题标题】:Convert key value pair string to HashMap in one line一行将键值对字符串转换为HashMap
【发布时间】:2021-03-30 01:39:41
【问题描述】:

我有一个字符串,内容如下:

key1:value1 key2:value2 key3:value3 ...

我希望得到一个 HashMap<&str, &str>(或等效项),它映射字符串中的键和值(例如,“key1”的哈希查找应该返回“value1”)。

目前,我可以轻松地使用以下内容填充 HashMap:

let mut hm = HashMap::new();
for item in my_string.split_ascii_whitespace() {
    let splits = item.split(":").collect::<Vec<&str>>();
    hm.insert(splits[0], splits[1]);
}

但是,如果我想在一行中完成(为了“代码高尔夫”之类的目的,即使以可读性为代价)怎么办?我知道如何使用HashSet 来做到这一点,所以我想它看起来会有些相似;也许是这样的(实际上并没有编译):

let hm: HashMap<&str, &str> = HashMap::from_iter(my_string.split_ascii_whitespace().map(|s| s.split(":").take(2).collect::<Vec<&str>>()));

我尝试了与上述类似的不同组合,但我似乎无法找到可以实际编译的东西。

【问题讨论】:

    标签: string parsing rust split hashmap


    【解决方案1】:

    我解决这个问题的方法是记住 Iterator&lt;Item=(K, V)&gt; 可以被收集到 HashMap&lt;K, V&gt; 中,所以在知道我向后工作试图弄清楚如何将 &amp;str 变成 Iterator&lt;Item=(&amp;str, &amp;str)&gt; 时我设法使用 String findsplit_at 方法:

    use std::collections::HashMap;
    
    fn one_liner(string: &str) -> HashMap<&str, &str> {
        string.split_whitespace().map(|s| s.split_at(s.find(":").unwrap())).map(|(key, val)| (key, &val[1..])).collect()
    }
    
    fn main() {
        dbg!(one_liner("key1:value1 key2:value2 key3:value3"));
    }
    

    playground

    第二个map 调用是从值字符串中删除前导: 字符所必需的。

    【讨论】:

    • 我明白了,split 只返回一个迭代器,而split_at 正好返回两个切片。看起来这可能只是这样做!谢谢
    猜你喜欢
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    • 2014-03-10
    • 2013-06-26
    • 2019-09-20
    相关资源
    最近更新 更多