在Rust中如何找到结构体中出现最频繁的字符串?

7
我需要查找 Vec<(String, Vec<String>)> 中第二个元素中出现频率最高的字符串。
use itertools::Itertools; // 0.8.0

fn main() {
    let edges: Vec<(String, Vec<String>)> = vec![];

    let x = edges
        .iter()
        .flat_map(|x| &x.1)
        .map(|x| &x[..])
        .sorted()
        .group_by(|x| x)
        .max_by_key(|x| x.len());
}

演练场

这段代码:

  • 获取迭代器
  • flat-map到元组的第二部分
  • 将元素转换为&str
  • 排序(通过itertools)
  • 按字符串进行分组(通过itertools)
  • 找到字符串出现最多的组

这样可以得到出现频率最高的字符串组,但是它不会编译:

error[E0599]: no method named `max_by_key` found for type `itertools::groupbylazy::GroupBy<&&str, std::vec::IntoIter<&str>, [closure@src/lib.rs:9:19: 9:24]>` in the current scope
  --> src/lib.rs:10:10
   |
10 |         .max_by_key(|x| x.len());
   |          ^^^^^^^^^^
   |
   = note: the method `max_by_key` exists but the following trait bounds were not satisfied:
           `&mut itertools::groupbylazy::GroupBy<&&str, std::vec::IntoIter<&str>, [closure@src/lib.rs:9:19: 9:24]> : std::iter::Iterator`

我对这些类型完全不了解。
1个回答

9
你没有阅读正在使用的函数文档。这不是一个好主意。

此类型实现了IntoIterator(它本身不是迭代器),因为组迭代器需要从该值中借用。它应该存储在局部变量或临时变量中并进行迭代。


个人意见,我会使用 BTreeMapHashMap

let mut counts = BTreeMap::new();
for word in edges.iter().flat_map(|x| &x.1) {
    *counts.entry(word).or_insert(0) += 1;
}

let max = counts.into_iter().max_by_key(|&(_, count)| count);

println!("{:?}", max);

如果你真的想使用迭代器,代码可能看起来像这样:

let groups = edges
    .iter()
    .flat_map(|x| &x.1)
    .sorted()
    .group_by(|&x| x);

let max = groups
    .into_iter()
    .map(|(key, group)| (key, group.count()))
    .max_by_key(|&(_, count)| count);

1
是的,你说对了。我来自函数式语言,那里的迭代器几乎没有这么多噪音。但是,Rust有很多好处来平衡这一点,所以我还在坚持。 - user8370684

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接