I’ve got a simple task: filter existing HashMap and clone it into a new variable in Rust.
The code I’ve tried:
let numbers: HashMap<u32, u32> = HashMap::from([
(1, 10),
(2, 20),
(3, 30),
]);
// Should retain only (2, 20)
let filtered: HashMap<u32, u32> = numbers
.iter()
.filter(|&(k, v)| *k < 3 && *v > 10)
.cloned()
.collect();
However, it doesn’t compile:
error[E0271]: expected `Filter<Iter<'_, u32, u32>, {[email protected]:15:17}>` to be an iterator that yields `&_`, but it yields `(&u32, &u32)`
--> src/main.rs:16:10
|
16 | .cloned()
| ^^^^^^ expected `&_`, found `(&u32, &u32)`
|
= note: expected reference `&_`
found tuple `(&u32, &u32)`
...
My colleague advised me with a working solution using filter_map
:
let filtered: HashMap<u32, u32> = numbers
.iter()
.filter_map(|(k, v)| (*k < 3 && *v > 10).then_some((*k, *v)))
.collect();
Note: you need to use .clone()
instead of dereferencing in filter_map
if you have a struct instead of primitive value.