问题描述
如何分割向量
let v: Vec<u8>; // vector with size x
let n: usize = 1024;
let chunks_list: Vec<Vec<u8>> = chunks(v,n);
或使用切片(以避免复制):
let v: &[u8];
let chunks_list: Vec<&[u8]> = chunks(v,n);
解决方法
Rust 切片已经包含了必要的方法:chunks。
从这里开始:
let src: Vec<u8> = vec![1,2,3,4,5];
您可以获得切片的向量(无副本):
let dst: Vec<&[u8]> = src.chunks(3).collect();
或向量的向量(较慢,较重):
let dst: Vec<Vec<u8>> = src.chunks(3).map(|s| s.into()).collect();
,
这是一种方法:
use std::{usize,vec};
fn chunks(data: Vec<u8>,chunk_size: usize) -> Vec<Vec<u8>> {
let mut results = vec![];
let mut current = vec![];
for i in data {
if current.len() >= chunk_size {
results.push(current);
current = vec![];
}
current.push(i);
}
results.push(current);
return results;
}
fn main() {
let v: Vec<u8> = (1..100).collect();
let n: usize = 24;
let chunks_list = chunks(v,n);
println!("{:#?}",chunks_list);
}
,
已有一个用于 slices 的方法:
pub fn chunks(&self,chunk_size: usize) -> Chunks<'_,T>
从切片的开头开始,一次返回对切片的 chunk_size
元素的迭代器。
块是切片并且不重叠。如果 chunk_size
不划分切片的长度,则最后一个块的长度将不会有 chunk_size
。
还有 chunks_mut
用于可变性以及 chunks_exact
和 chunks_exact_mut
,如果最后一个块必须遵守大小 n
,以及不安全的 {{3}如果我们假设没有余数,请参见以下示例:
fn main() {
let v: [u8; 5] = *b"lorem";
let n = 2;
let chunks = v.chunks(n);
let chunks_list: Vec<&[u8]> = chunks.collect();
println!("{:?}",chunks_list);
}
使用切片代替向量有一些as_chunks_unchecked
,特别是避免了复制的开销。
如果需要将一个 Vec
拆分成多个 Vec
,我会使用 Itertools::chunks
。这需要一个迭代器并返回一个迭代器的迭代器。然后您可以选择将内部和外部迭代器收集到 Vec
s:
use itertools::Itertools; // 0.10.0
fn main() {
let v = vec![String::from("A"),String::from("B"),String::from("C")];
let x: Vec<Vec<String>> = v.into_iter().chunks(2).into_iter().map(|c| c.collect()).collect();
eprintln!("{:?}",x);
}
[["A","B"],["C"]]
这样做的好处是可以拥有原始向量中每个值的所有权。不需要复制数据,但需要移动。如果您可以改用切片,那么使用 slice::chunks
会更好。