HiveBrain v1.2.0
Get Started
← Back to all entries
snippetrustModerate

How do I collect the values of a HashMap into a vector?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
howthecollecthashmapvectorvaluesinto

Problem

I can not find a way to collect the values of a HashMap into a Vec in the documentation. I have score_table: HashMap and I want to get all the Scores into all_scores: Vec.

I was tempted to use the values method (all_scores = score_table.values()), but it does not work since values is not a Vec.

I know that Values implements the ExactSizeIterator trait, but I do not know how to collect all values of an iterator into a vector without manually writing a for loop and pushing the values in the vector one after one.

I also tried to use std::iter::FromIterator; but ended with something like:

all_scores = Vec::from_iter(score_table.values());


expected type std::vec::Vec
found type
std::vec::Vec


Thanks to Hash map macro refuses to type-check, failing with a misleading (and seemingly buggy) error message?, I changed it to:

all_scores = Vec::from_iter(score_table.values().cloned());


and it does not produce errors to cargo check.

Is this a good way to do it?

Solution

There are three useful methods1 on HashMaps, which all return iterators:

  • values() borrows the collection and returns references (&T).



  • values_mut() gives mutable references &mut T which is useful to modify elements of the collection without destroying score_table.



  • into_values() gives you the elements directly: T! The iterator takes ownership of all the elements. This means that score_table no longer owns them, so you can't use score_table anymore!



In your example, you call values() to get &T references, then convert them to owned values T via a clone(), which creates potentially expensive copies.

Instead, if we have an iterator of owned values, then we can convert it to a Vec using Iterator::collect():
let all_scores: Vec = score_table.into_values().collect();


Sometimes, you may need to specify the collecting type:
let all_scores = score_table.into_values().collect::>();


1 This is a common pattern in Rust. In the standard library, and popular crates, you'll often find functions with these (into)_thing_(mut) names, with the presence or absence of these functions letting you know what you can do with that object.

Context

Stack Overflow Q#56724014, score: 30

Revisions (0)

No revisions yet.