收集到 HashMap 时是否可以检测冲突?
Is it possible to detect collisions when collecting into a HashMap?
我想在将 IntoIterator
收集到 HashMap
时检测日志中的冲突并发出警告。当前收集到 HashMap
中的 Rust 行为是用最新的值默默地覆盖较早的值。
fn main() {
let a = vec![(0, 1), (0, 2)];
let b: std::collections::HashMap<_, _> = a.into_iter().collect();
println!("{}", b[&0]);
}
输出:
2
一个可能的解决方法是收集到 Vec
然后手动编写转换代码,但这会引入额外的分配开销和不可读的代码。不消耗原始集合并比较 len()
s 噪音较小,但仍然占用 1 倍以上的内存(?)并且无法检测到碰撞发生的确切位置。
是否有更优雅的方式来处理 HashMap
碰撞?
根据发生碰撞时您想做什么,您可以使用 fold
(或 try_fold
)和 entry API 来实现您的自定义功能:
use std::collections::HashMap;
fn main() {
let a = vec![(0, 1), (0, 3), (0, 2)];
let b: std::collections::HashMap<_, _> = a.into_iter().fold(HashMap::new(), |mut map, (k,v)| {
map.entry(k)
.and_modify(|_| println!("Collision with {}, {}!", k, v))
.or_insert(v);
map
});
println!("{}", b[&0]);
}
我想在将 IntoIterator
收集到 HashMap
时检测日志中的冲突并发出警告。当前收集到 HashMap
中的 Rust 行为是用最新的值默默地覆盖较早的值。
fn main() {
let a = vec![(0, 1), (0, 2)];
let b: std::collections::HashMap<_, _> = a.into_iter().collect();
println!("{}", b[&0]);
}
输出:
2
一个可能的解决方法是收集到 Vec
然后手动编写转换代码,但这会引入额外的分配开销和不可读的代码。不消耗原始集合并比较 len()
s 噪音较小,但仍然占用 1 倍以上的内存(?)并且无法检测到碰撞发生的确切位置。
是否有更优雅的方式来处理 HashMap
碰撞?
根据发生碰撞时您想做什么,您可以使用 fold
(或 try_fold
)和 entry API 来实现您的自定义功能:
use std::collections::HashMap;
fn main() {
let a = vec![(0, 1), (0, 3), (0, 2)];
let b: std::collections::HashMap<_, _> = a.into_iter().fold(HashMap::new(), |mut map, (k,v)| {
map.entry(k)
.and_modify(|_| println!("Collision with {}, {}!", k, v))
.or_insert(v);
map
});
println!("{}", b[&0]);
}