如何将元素为(K0,K1,V)的3元组迭代器转换为HashMap<K0,HashMap<K1,V>>
Rust 嵌套HashMap转换函数实现
标准库无依赖最优实现(函数式风格)
直接使用迭代器fold结合EntryAPI即可写出无额外依赖、零冗余开销的实现:
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)>, { input.into_iter().fold(HashMap::new(), |mut outer, (k0, k1, v)| { outer.entry(k0).or_insert_with(HashMap::new).insert(k1, v); outer }) }
实现说明
- 整体采用函数式折叠(fold)逻辑,无显式手动循环,初始累加值为空的外层HashMap
- 利用
EntryAPI避免重复哈希计算,or_insert_with惰性初始化内层HashMap,不会产生无用的临时对象 - 重复的
(K0, K1)组合会默认用后出现的V覆盖之前的值,和标准库HashMap::insert行为保持一致,如有聚合需求可修改insert部分的逻辑(例如内层存Vec<V>批量收集值)
可选:基于itertools的分组实现
如果项目已经引入itertools依赖,也可以用分组写法,逻辑可读性更强:
use std::collections::HashMap; use std::hash::Hash; use itertools::Itertools; fn transform<K0, K1, V, I>(input: I) -> HashMap<K0, HashMap<K1, V>> where K0: Hash + Eq + Clone, K1: Hash + Eq, I: IntoIterator<Item = (K0, K1, V)>, { input .into_iter() .group_by(|(k0, _, _)| k0.clone()) .into_iter() .map(|(k0, group)| { let inner = group.map(|(_, k1, v)| (k1, v)).collect(); (k0, inner) }) .collect() }
注意该实现要求K0实现Clone trait,性能和标准库实现无本质差异。
内容的提问来源于stack exchange,提问作者DMaster
相关产品推荐
相关产品推荐

