I am a newbie in Rust, and I am having trouble understanding Itertools::GroupBy
.
Here is an example I came up with to practice GroupBy
. Given an array of integers:
- Group it based on the value of the numbers.
- Keep only groups with more than 3 elements.
- Return a vector with the keys of the survived groups.
As an example, given this array
[1,1,1,1,-2,-2,-3,-3,-3,-3,4,4]
I want to return the vector (1,-3)
, because 1 and 3 appears more than three times in the array.
Here is my attempt
let groups = [1, 1, 1, 1, -2, -2, -3, -3, -3, -3, 4, 4]
.into_iter()
.group_by(|element| *element)
.into_iter()
.filter(|(_, value)| value.count() > 3)
.map(|(key, _)| key)
.collect::<Vec<i32>>();
You can try this out in the Rust playground.
The line with the filter results in the error: "cannot move out of *value
which is behind a shared reference", where *value
is moved due to the method call count()
.
After experimenting, I notice that I can fix the code adding a map
let groups = [1, 1, 1, 1, -2, -2, -3, -3, -3, -3, 4, 4]
.into_iter()
.group_by(|element| *element)
.into_iter()
.map(|(key, value)| (key, value.collect::<Vec<i32>>()))
.filter(|(_, value)| value.len() > 3)
.map(|(key, _)| key)
.collect::<Vec<i32>>();
However, I would like to understand why my original attempt is not working. I understand that it has to do with borrowing, but my knowledge is still too basic.