Rust中如何筛选指定范围不在向量内的元素并收集为Vec<i32>
问题分析与解决
你的代码核心问题是遍历对象搞反了:你需要筛选的是range中不在vec里的元素,但你现在是遍历vec的元素,过滤出不在range里的——而你的vec所有元素都在range范围内,所以结果为空,自然不符合预期。
另外,要收集成Vec<i32>而非Vec<&i32>,只需确保迭代的是i32类型的元素,而非引用。
解法一:直接使用Vec查询(适合小向量)
如果你的vec元素数量不多,直接用vec.contains()查询即可:
fn main() { let range = 0..10; let vec = vec![0,2,4,6,8]; let result: Vec<i32> = range.filter(|x| !vec.contains(x)).collect(); println!("{:?}", result); // 输出 [1,3,5,7,9] }
- 遍历
range(元素是i32),过滤出不在vec中的元素,直接收集为Vec<i32>。 vec.contains(x)中,x是&i32类型(因为range.filter闭包接收的是元素的引用),而vec是Vec<i32>,contains方法接受&i32参数,刚好匹配。
解法二:用HashSet优化查询效率(适合大向量)
如果vec元素很多,每次vec.contains()是O(n)复杂度,转成HashSet可以把查询降到O(1):
use std::collections::HashSet; fn main() { let range = 0..10; let vec = vec![0,2,4,6,8]; let num_set: HashSet<_> = vec.into_iter().collect(); let result: Vec<i32> = range.filter(|x| !num_set.contains(x)).collect(); println!("{:?}", result); // 输出 [1,3,5,7,9] }
vec.into_iter()会消耗原向量,把元素转移到HashSet中;如果还要保留原向量,可以用vec.iter().copied().collect()。
原代码的类型问题补充
如果只是想把Vec<&i32>转成Vec<i32>,可以在iter()后调用copied()(适用于实现Copy的类型,比如i32)或cloned():
// 仅作类型转换示例,逻辑仍错误,无法得到预期结果 let x = vec.iter().copied().filter(|&x| !range.contains(x)).collect::<Vec<i32>>();
但这解决不了你核心的逻辑错误,所以优先调整遍历对象。
内容的提问来源于stack exchange,提问作者HWilmer
相关产品推荐
相关产品推荐

