如何在Rust中从HashMap提取条目并转移至另一个HashMap
Rust实现HashMap条目提取转移功能
对应你提供的C++代码功能:从原HashMap中提取值大于200的条目,转移至新的HashMap,同时移除原HashMap中的对应条目。
C++参考实现
#include <iostream> #include <unordered_map> void print(const std::unordered_map<std::string, int>& data) { for (const auto&[key, val] : data) { std::cout << key << ": " << val << "\n"; } std::cout << std::endl; } std::unordered_map<std::string, int> extract(std::unordered_map<std::string, int>& mapp) { std::unordered_map<std::string, int> mappp; for (auto itr = mapp.begin(); itr != mapp.end(); ) { if (itr->second > 200) { auto prev_itr = itr++; mappp.insert(mapp.extract(prev_itr)); } else { ++itr; } } return mappp; } int main() { std::unordered_map<std::string, int> mapp { {"abc", 123}, {"def", 67}, {"ghi", 380}, {"jkl", 4376} }; print(mapp); auto mappp = extract(mapp); print(mapp); print(mappp); }
补全后的Rust实现
方法一:使用drain_filter(推荐,高效)
drain_filter是HashMap的内置方法,可直接筛选并移除符合条件的条目,返回的迭代器可直接收集为新HashMap:
use std::collections::HashMap; fn print(mapp: &HashMap<String, i32>) { for (key, val) in mapp { println!("{}: {}", key, val); } println!(""); } fn extract(mapp: &mut HashMap<String, i32>) -> HashMap<String, i32> { // 筛选值大于200的条目,同时从原HashMap移除并收集到新HashMap mapp.drain_filter(|_, &mut val| val > 200).collect() } fn main() { let mut mapp: HashMap<String, i32> = HashMap::new(); mapp.insert("abc".to_string(), 123); mapp.insert("def".to_string(), 67); mapp.insert("ghi".to_string(), 380); mapp.insert("jkl".to_string(), 4376); print(&mapp); let mappp = extract(&mut mapp); print(&mapp); print(&mappp); }
方法二:先收集符合条件的键,再逐个移除
若需兼容更早的Rust版本(drain_filter在Rust 1.63+稳定版才支持),可先收集目标键再逐个提取:
use std::collections::HashMap; fn print(mapp: &HashMap<String, i32>) { for (key, val) in mapp { println!("{}: {}", key, val); } println!(""); } fn extract(mapp: &mut HashMap<String, i32>) -> HashMap<String, i32> { // 先收集所有值大于200的键(克隆键避免迭代时修改原HashMap的冲突) let keys_to_extract: Vec<String> = mapp .iter() .filter(|(_, &val)| val > 200) .map(|(key, _)| key.clone()) .collect(); let mut new_map = HashMap::new(); for key in keys_to_extract { // 移除原HashMap条目并插入新HashMap if let Some((k, v)) = mapp.remove_entry(&key) { new_map.insert(k, v); } } new_map } fn main() { let mut mapp: HashMap<String, i32> = HashMap::new(); mapp.insert("abc".to_string(), 123); mapp.insert("def".to_string(), 67); mapp.insert("ghi".to_string(), 380); mapp.insert("jkl".to_string(), 4376); print(&mapp); let mappp = extract(&mut mapp); print(&mapp); print(&mappp); }
说明
- 方法一的
drain_filter直接操作原HashMap,无需额外克隆键,性能更优。 - 方法二逻辑直观,兼容更早的Rust版本,适合对版本有要求的场景。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

