I can not find a way to collect the values of a HashMap
into a Vec
in the documentation. I have score_table: HashMap<Id, Score>
and I want to get all the Score
s into all_scores: Vec<Score>
.
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<Score>`
found type `std::vec::Vec<&Score>`
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?
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> = score_table.into_values().collect();
Sometimes, you may need to specify the collecting type:
let all_scores = score_table.into_values().collect::<Vec<Score>>();
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.