snippetrustCritical
How do I create a map from a list in a functional way?
Viewed 0 times
howfromcreatefunctionallistwaymap
Problem
In Scala, there is a method named
What is the closest thing to
toMap that works on any list of tuples and converts it to a map where the key is the first item on the tuple and the value is the second one:val listOfTuples = List(("one", 1), ("two", 2))
val map = listOfTuples.toMap
What is the closest thing to
toMap in Rust?Solution
Use
Said another way, any iterator of tuples where the first value can be hashed and compared for total equality can be converted to a
With this knowledge, you can also call
See also:
what change should I make so that I get all the values with same key stored in a
There's no one-line / functional method for this in the standard library. Instead, use the
If you found yourself doing this frequently, you could create your own type and implement
See also:
Iterator::collect:use std::collections::HashMap;
fn main() {
let tuples = [("one", 1), ("two", 2), ("three", 3)];
let m: HashMap = tuples.into_iter().collect();
println!("{:?}", m);
}collect leverages the FromIterator trait. Any iterator can be collected into a type that implements FromIterator. In this case, HashMap implements it as:impl FromIterator for HashMap
where
K: Eq + Hash,
S: HashState + Default,Said another way, any iterator of tuples where the first value can be hashed and compared for total equality can be converted to a
HashMap. The S parameter isn't exciting to talk about, it just defines what the hashing method is.With this knowledge, you can also call
FromIterator directly:use std::collections::HashMap;
fn main() {
let m: HashMap = HashMap::from_iter([("one", 1), ("two", 2), ("three", 3)]);
println!("{:?}", m);
}See also:
- Collect iterators of length 2 into HashMap
- How do I create a HashMap literal?
what change should I make so that I get all the values with same key stored in a
Vec?There's no one-line / functional method for this in the standard library. Instead, use the
entry API:use std::collections::HashMap;
fn main() {
let tuples = vec![("one", 1), ("two", 2), ("one", 3)];
let mut m = HashMap::new();
for (k, v) in tuples {
m.entry(k).or_insert_with(Vec::new).push(v)
}
println!("{:?}", m);
}If you found yourself doing this frequently, you could create your own type and implement
FromIterator for it:use std::{cmp::Eq, collections::HashMap, hash::Hash, iter::FromIterator};
struct MyCoolType(HashMap>);
impl FromIterator for MyCoolType {
fn from_iter(tuples: I) -> Self
where
I: IntoIterator,
{
let mut m = HashMap::new();
for (k, v) in tuples {
m.entry(k).or_insert_with(Vec::new).push(v)
}
Self(m)
}
}
fn main() {
let tuples = vec![("one", 1), ("two", 2), ("one", 3)];
let MyCoolType(m) = tuples.into_iter().collect();
println!("{:?}", m);
}See also:
- How to lookup from and insert into a HashMap efficiently?
Code Snippets
use std::collections::HashMap;
fn main() {
let tuples = [("one", 1), ("two", 2), ("three", 3)];
let m: HashMap<_, _> = tuples.into_iter().collect();
println!("{:?}", m);
}impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S>
where
K: Eq + Hash,
S: HashState + Default,use std::collections::HashMap;
fn main() {
let m: HashMap<_, _> = HashMap::from_iter([("one", 1), ("two", 2), ("three", 3)]);
println!("{:?}", m);
}use std::collections::HashMap;
fn main() {
let tuples = vec![("one", 1), ("two", 2), ("one", 3)];
let mut m = HashMap::new();
for (k, v) in tuples {
m.entry(k).or_insert_with(Vec::new).push(v)
}
println!("{:?}", m);
}use std::{cmp::Eq, collections::HashMap, hash::Hash, iter::FromIterator};
struct MyCoolType<K: Eq + Hash, V>(HashMap<K, Vec<V>>);
impl<K: Eq + Hash, V> FromIterator<(K, V)> for MyCoolType<K, V> {
fn from_iter<I>(tuples: I) -> Self
where
I: IntoIterator<Item = (K, V)>,
{
let mut m = HashMap::new();
for (k, v) in tuples {
m.entry(k).or_insert_with(Vec::new).push(v)
}
Self(m)
}
}
fn main() {
let tuples = vec![("one", 1), ("two", 2), ("one", 3)];
let MyCoolType(m) = tuples.into_iter().collect();
println!("{:?}", m);
}Context
Stack Overflow Q#30441698, score: 143
Revisions (0)
No revisions yet.