如何按6元素块移除Vec各块末尾3元素?无中间分配的迭代器实现
Rust 无中间分配的分块过滤实现
要实现你需求的效果,完全可以通过迭代器组合操作做到无中间临时分配(仅最终结果的Vec会分配内存),下面提供两种简洁的实现方式:
方法一:分块后取前N元素
利用chunks_exact按固定大小分块,再通过flat_map直接展开每个块的前3个元素迭代器,避免创建中间小型Vec:
fn main() { let v = vec![1,2,3,4,5,6,7,8,9,10,11,12]; let result: Vec<_> = v.chunks_exact(6) .flat_map(|chunk| chunk.iter().take(3)) .copied() // 元素类型为Copy时用copied,非Copy类型改用cloned .collect(); assert_eq!(result, vec![1,2,3,7,8,9]); }
chunks_exact(6):将原Vec严格分割为每个6元素的块(若原长度不是6的倍数,剩余元素会被忽略;需保留剩余元素可改用chunks)flat_map:直接将每个块的前3元素迭代器展开,无需存储中间块的临时集合copied/cloned:将切片引用转换为具体值,根据元素类型选择即可
方法二:通过索引过滤
直接遍历所有元素,根据索引判断是否属于每个块的前3个位置,逻辑更直观:
fn main() { let v = vec![1,2,3,4,5,6,7,8,9,10,11,12]; let result: Vec<_> = v.iter() .enumerate() .filter(|(idx, _)| idx % 6 < 3) .map(|(_, val)| *val) // Copy类型直接解引用即可,非Copy类型用clone .collect(); assert_eq!(result, vec![1,2,3,7,8,9]); }
这种方式无需分块操作,直接通过索引模运算筛选目标元素,同样没有中间分配开销。
注意:因为最终结果的元素在原Vec中并非连续存储(1-3和7-9之间间隔了4-6),所以无法直接得到原Vec的子切片,必须收集为新的Vec。
内容的提问来源于stack exchange,提问作者daniellga
相关产品推荐
相关产品推荐

