yegor256
yegor256

Reputation: 105053

How to count HashMap values using a predicate in Rust?

I'm trying this, but doesn't work:

let map = HashMap::new();
map.insert(1, "aaa");
map.insert(2, "bbb");
let a = map.counts_by(|k, v| v.starts_with("a"));

What is the right way?

Upvotes: 1

Views: 1341

Answers (2)

Silvio Mayolo
Silvio Mayolo

Reputation: 70267

Anything that iterates over collections in Rust is going to factor through the Iterator API, and unlike in Java where iterators are often implicitly used, it's very common in Rust to explicitly ask for an iterator (with .iter()) and do some work directly on it in a functional style. In your case, there are three things we need to do here.

  1. Get the values of the HashMap. This can be done with the values method, which returns an iterator.
  2. Keep only the ones satisfying a particular predicate. This is a filter operation and will produce another iterator. Note that this does not yet iterate over the hash map; it merely produces another iterator capable of doing so later.
  3. Count the matches, using count.

Putting it all together, we have

map.values().filter(|v| v.starts_with("a")).count()

Upvotes: 5

Jeremy Meadows
Jeremy Meadows

Reputation: 2561

You should filter an iterator of the HashMap, then count the elements of the iterator:

use std::collections::HashMap;

fn main() {
    let mut map = HashMap::new();
    map.insert(1, "aaa");
    map.insert(2, "bbb");

    assert_eq!(
        map.iter().filter(|(_k, v)| v.starts_with("a")).count(),
        1
    );
}

Notice that the map also has to be marked as mut in order to insert new elements, and the filter closure destructures into a tuple containing the key and the value, rather than accepting two separate parameters.

Upvotes: 2

Related Questions