使用折叠迭代器方法在 Rust 中创建 HashMap
Creating a HashMap in Rust using the fold iterator method
我正在尝试使用 Entry 和 Rust 中的迭代器从一组单词创建一个单词计数 HashMap。当我尝试如下时,
use std::collections::HashMap;
fn main () {
let corpus = ["foo", "bar", "bar", "grok", "blah", "foo", "bar"];
let mut word_count = corpus.iter().fold(HashMap::new(), |mut acc, word| *acc.entry(word).or_insert(0) += 1);
println!("{:?}", word_count);
}
我收到错误:预期结构 HashMap
,找到 ()
,类型不匹配。
我可以通过创建一个新范围并显式返回累加器来让它工作:
use std::collections::HashMap;
fn main () {
let corpus = ["foo", "bar", "bar", "grok", "blah", "foo", "bar"];
let mut word_count = corpus.iter().fold(HashMap::new(), |mut acc, word|{
*acc.entry(word).or_insert(0) += 1;
acc
});
println!("{:?}", word_count);
}
我得到了预期的 {"foo": 2, "bar": 3, "blah": 1, "grok": 1}
。
通常 fold
returns 累加器的最后状态,所以我期待第一种方法起作用,但不清楚为什么它不起作用。非常感谢对替代方法(使用迭代器)的一些说明和任何建议。
就像@PitaJ 的评论中解释的那样,*acc.entry(word).or_insert(0) += 1
具有类型 ()
,而编译器每次都期望 fold()
回调到 return 下一个状态(有时在其他语言中称为 reduce()
,例如 JavaScript;在 Rust 中;fold()
允许您指定起始值,而 reduce()
从迭代器).
正因为如此,我觉得它更适合循环的用例,因为你不需要 return 一个新的状态,而是更新地图:
let mut word_count = HashMap::new();
for word in &corpus {
*word_count.entry(word).or_insert(0) += 1;
}
但是,如果您愿意,itertools
箱子中有一个方法可以做到这一点:counts()
:
let word_count = corpus.iter().counts();
我正在尝试使用 Entry 和 Rust 中的迭代器从一组单词创建一个单词计数 HashMap。当我尝试如下时,
use std::collections::HashMap;
fn main () {
let corpus = ["foo", "bar", "bar", "grok", "blah", "foo", "bar"];
let mut word_count = corpus.iter().fold(HashMap::new(), |mut acc, word| *acc.entry(word).or_insert(0) += 1);
println!("{:?}", word_count);
}
我收到错误:预期结构 HashMap
,找到 ()
,类型不匹配。
我可以通过创建一个新范围并显式返回累加器来让它工作:
use std::collections::HashMap;
fn main () {
let corpus = ["foo", "bar", "bar", "grok", "blah", "foo", "bar"];
let mut word_count = corpus.iter().fold(HashMap::new(), |mut acc, word|{
*acc.entry(word).or_insert(0) += 1;
acc
});
println!("{:?}", word_count);
}
我得到了预期的 {"foo": 2, "bar": 3, "blah": 1, "grok": 1}
。
通常 fold
returns 累加器的最后状态,所以我期待第一种方法起作用,但不清楚为什么它不起作用。非常感谢对替代方法(使用迭代器)的一些说明和任何建议。
就像@PitaJ 的评论中解释的那样,*acc.entry(word).or_insert(0) += 1
具有类型 ()
,而编译器每次都期望 fold()
回调到 return 下一个状态(有时在其他语言中称为 reduce()
,例如 JavaScript;在 Rust 中;fold()
允许您指定起始值,而 reduce()
从迭代器).
正因为如此,我觉得它更适合循环的用例,因为你不需要 return 一个新的状态,而是更新地图:
let mut word_count = HashMap::new();
for word in &corpus {
*word_count.entry(word).or_insert(0) += 1;
}
但是,如果您愿意,itertools
箱子中有一个方法可以做到这一点:counts()
:
let word_count = corpus.iter().counts();