如何以功能方式从列表创建地图?
How do I create a map from a list in a functional way?
在 Scala 中,有一个名为 toMap
的方法适用于任何元组列表并将其转换为映射,其中键是元组中的第一项,值是第二项:
val listOfTuples = List(("one", 1), ("two", 2))
val map = listOfTuples.toMap
Rust 中最接近 toMap
的东西是什么?
use std::collections::HashMap;
fn main() {
let tuples = [("one", 1), ("two", 2), ("three", 3)];
let m: HashMap<_, _> = tuples.into_iter().collect();
println!("{:?}", m);
}
collect
利用 FromIterator
trait。任何迭代器都可以收集到实现 FromIterator
的类型中。在这种情况下,HashMap
将其实现为:
impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S>
where
K: Eq + Hash,
S: HashState + Default,
换句话说,第一个值可以 be hashed and compared for total equality 的任何元组迭代器都可以转换为 HashMap
。 S
这个参数说起来并不刺激,它只是定义了哈希方法是什么。
有了这些知识,你也可以直接调用FromIterator
:
use std::collections::HashMap;
fn main() {
let m: HashMap<_, _> = HashMap::from_iter([("one", 1), ("two", 2), ("three", 3)]);
println!("{:?}", m);
}
另请参阅:
- 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
?
标准库中没有用于此的单行/功能方法。相反,使用 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);
}
如果您发现自己经常这样做,您可以创建自己的类型并为其实现 FromIterator
:
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);
}
另请参阅:
由于尚未提及,这里是单行(虽然很长)方法:
use std::collections::HashMap;
fn main() {
let m: HashMap<&str, u16> = [("year", 2019), ("month", 12)].iter().cloned().collect();
println!("{:?}", m);
}
或者你可以做一个特质:
use std::collections::HashMap;
trait Hash {
fn to_map(&self) -> HashMap<&str, u16>;
}
impl Hash for [(&str, u16)] {
fn to_map(&self) -> HashMap<&str, u16> {
self.iter().cloned().collect()
}
}
fn main() {
let m = [("year", 2019), ("month", 12)].to_map();
println!("{:?}", m)
}
https://doc.rust-lang.org/std/collections/struct.HashMap.html#examples
let map = HashMap::from([
("one", 1),
("two", 2)
]);
在 Scala 中,有一个名为 toMap
的方法适用于任何元组列表并将其转换为映射,其中键是元组中的第一项,值是第二项:
val listOfTuples = List(("one", 1), ("two", 2))
val map = listOfTuples.toMap
Rust 中最接近 toMap
的东西是什么?
use std::collections::HashMap;
fn main() {
let tuples = [("one", 1), ("two", 2), ("three", 3)];
let m: HashMap<_, _> = tuples.into_iter().collect();
println!("{:?}", m);
}
collect
利用 FromIterator
trait。任何迭代器都可以收集到实现 FromIterator
的类型中。在这种情况下,HashMap
将其实现为:
impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S>
where
K: Eq + Hash,
S: HashState + Default,
换句话说,第一个值可以 be hashed and compared for total equality 的任何元组迭代器都可以转换为 HashMap
。 S
这个参数说起来并不刺激,它只是定义了哈希方法是什么。
有了这些知识,你也可以直接调用FromIterator
:
use std::collections::HashMap;
fn main() {
let m: HashMap<_, _> = HashMap::from_iter([("one", 1), ("two", 2), ("three", 3)]);
println!("{:?}", m);
}
另请参阅:
- 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
?
标准库中没有用于此的单行/功能方法。相反,使用 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);
}
如果您发现自己经常这样做,您可以创建自己的类型并为其实现 FromIterator
:
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);
}
另请参阅:
由于尚未提及,这里是单行(虽然很长)方法:
use std::collections::HashMap;
fn main() {
let m: HashMap<&str, u16> = [("year", 2019), ("month", 12)].iter().cloned().collect();
println!("{:?}", m);
}
或者你可以做一个特质:
use std::collections::HashMap;
trait Hash {
fn to_map(&self) -> HashMap<&str, u16>;
}
impl Hash for [(&str, u16)] {
fn to_map(&self) -> HashMap<&str, u16> {
self.iter().cloned().collect()
}
}
fn main() {
let m = [("year", 2019), ("month", 12)].to_map();
println!("{:?}", m)
}
https://doc.rust-lang.org/std/collections/struct.HashMap.html#examples
let map = HashMap::from([
("one", 1),
("two", 2)
]);