我是一位生疏的新手,我很难理解Itertools::GroupBy。
下面是我为练习GroupBy而提出的一个例子。给定一个整数数组:
作为一个例子,给定这个数组
[1,1,1,1,-2,-2,-3,-3,-3,-3,4,4]我想返回向量(1,-3),因为1和3在数组中出现超过三次。
这是我的尝试
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>>();您可以在生锈操场中试用这种方法。
带过滤器的行导致错误:“无法从共享引用后面的*value中移出”,其中*value由于方法调用count()而被移动。
在实验之后,我注意到我可以修复添加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>>();不过,我想知道我原来的尝试为何行不通。我知道这与借贷有关,但我的知识还是太基础了。
发布于 2022-07-30 17:21:07
.filter()不会给你项目的所有权,它甚至不会给你可变的东西,它只会给你不可变的引用。它期望您从不变的输入中推断出是否应该保留或删除某些内容。只要绕过这些项,.filter()就不会修改它们,而只是选择它们。
但是,要了解组中有多少值,就必须对其进行迭代,因为value变量是迭代器。但是,您不能迭代它,因为出于明显的原因,会修改value变量,这在.filter()中是不允许的。
不过,有一个解决方案:.filter_map()方法将.filter()和.map()组合在一个操作中,并为您提供所拥有的元素,以及您喜欢的元素:
use itertools::Itertools;
fn main() {
let groups = [1, 1, 1, 1, -2, -2, -3, -3, -3, -3, 4, 4]
.into_iter()
.group_by(|element| *element)
.into_iter()
.filter_map(|(key, value)| (value.count() > 3).then_some(key))
.collect::<Vec<i32>>();
println!("{:?}", groups);
}[1, -3]https://stackoverflow.com/questions/73177547
复制相似问题