如何从HashMap
中提取条目并将其传输到Rust中的另一个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等价(extract
函数不完整)
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> {
// mapp.iter().filter(&|(_, val)| val > 200)
HashMap::new()
}
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);
}
型
2条答案
按热度按时间b5buobof1#
由于
drain_filter
还不稳定,一个不太理想的选择(因为更多的分配和更多的流量)是将drain
原始Map将其内容分发到 * 两个 * 目标,然后将旧Map设置为其中一个目标字符串
一个可能稍微更有效的替代方案是将旧的条目收集到
Vec
中,然后extend()
旧的Map:型
它仍然需要重新散列和重新分发重新插入的条目,但对于较大的数据大小,它应该具有较低的内存高水位线,因为vec需要的空间比map少。它还可以避免丢弃与
mapp
相关联的分配,这取决于它的usd方式,此后可能会有用。然而,一个更老的替代方案是直接依赖于
hashbrown
,这是标准Map的实际底层实现,以及it addeddrain_filter
back in late 2019。bjp0bcyl2#
为了高效地完成这项工作,您需要
extract_if
*,目前它是每晚一次的。字符串
我把它设为通用的,这样就可以和其他方法进行比较。
如果你想在stable rust上使用它,你可以使用hashbrown crate,这是标准库目前在内部使用的。几乎所有来自std的API都是hashbrown格式的,还有一些东西,比如
extract_if
。在稳定的rust中,一个几乎完美的方法是使用
retain
。这需要克隆键并替换值,对于大多数哈希Map来说,这会很快,但是使用String
键使这并不理想。型
如果这些值没有实现
Default
,则可以使用占位符值。其他的答案对于真正的通用键和值是好的。
下面是一个使用
partition
的例子。型
这些方法的缺点是它会丢弃原始分配并创建两个新的分配,而其他方法会重用原始分配。
extract_if
最近被重命名,所以目前它只能在nightly std库中在线可见。现在,stable std(显示从最后一个stable发布时起的每晚特性)称之为drain_filter
。