Поиск наиболее часто встречающейся строки в структуре в Rust? - PullRequest
0 голосов
/ 01 марта 2019

Я ищу строку, которая чаще всего встречается во второй части кортежа 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());
}

Playground

Это:

  • принимает итератор
  • плоские карты во вторую часть кортежа
  • превращает элементы в &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 Ответ

0 голосов
/ 01 марта 2019

Вы не прочитали документацию для функции, которую вы используете .Это не хорошая идея.

Этот тип реализует IntoIterator (это не сам итератор), потому что групповые итераторы должны заимствоватьиз этого значения.Он должен храниться в локальной или временной переменной и повторяться.


Лично я бы просто использовал BTreeMap или HashMap:

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);
...