上面的标题应该足以解释这个问题,如果不是,那么下面的代码片段就足够了。
fn transform<K0, K1, V, I>(input: I) -> HashMap<K0, HashMap<K1, V>>
where
K0: Hash + Eq,
K1: Hash + Eq,
I: IntoIterator<Item = (K0, K1, V)>,
{
// what is the most elegant (preferably functional) way to do this?
}发布于 2021-10-22 12:23:56
一种“函数式”的方法就是使用fold。但我更喜欢显式循环。
fn transform2<K0, K1, V, I>(input: I) -> HashMap<K0, HashMap<K1, V>>
where
K0: Hash + Eq,
K1: Hash + Eq,
I: IntoIterator<Item = (K0, K1, V)>,
{
input
.into_iter()
.fold(HashMap::new(), |mut h, (k0, k1, v)| {
h.entry(k0).or_default().insert(k1, v);
h
})
}发布于 2021-10-22 12:22:33
在这种情况下,一个简单的循环就可以了:
use std::collections::HashMap;
use std::hash::Hash;
fn transform<K0, K1, V, I>(input: I) -> HashMap<K0, HashMap<K1, V>>
where
K0: Hash + Eq,
K1: Hash + Eq,
I: IntoIterator<Item = (K0, K1, V)>,
{
let mut result_map = HashMap::new();
for (k0, k1, v) in input {
result_map.entry(k0).or_insert_with(HashMap::new).insert(k1, v);
}
result_map
}发布于 2021-10-22 12:22:02
来自Rust论坛的用户Hyeonu提供了一个很好的答案(link):
fn transform<K0, K1, V, I>(input: I) -> HashMap<K0, HashMap<K1, V>>
where
K0: Hash + Eq,
K1: Hash + Eq,
I: IntoIterator<Item = (K0, K1, V)>,
{
let mut m = HashMap::<K0, HashMap<K1, V>>::new();
for (k0, k1, v) in input {
m.entry(k0).or_default().insert(k1, v);
}
m
}https://stackoverflow.com/questions/69676476
复制相似问题