【问题标题】:How can I split a vector into smaller vectors of size N?如何将向量拆分为大小为 N 的较小向量?
【发布时间】:2021-04-08 16:23:26
【问题描述】:

如何分割向量

let v: Vec<u8>; // vector with size x

到一个最大大小为 n 的向量的向量中?伪代码:

let n: usize = 1024;
let chunks_list: Vec<Vec<u8>> = chunks(v, n);

或使用切片(避免复制):

let v: &[u8]; 
let chunks_list: Vec<&[u8]> = chunks(v, n);

【问题讨论】:

    标签: vector rust


    【解决方案1】:

    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();
    

    playground

    【讨论】:

      【解决方案2】:

      这是一种方法:

      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);
      }
      

      【讨论】:

        【解决方案3】:

        如果需要Vec 拆分为多个Vecs,我会使用Itertools::chunks。这需要一个迭代器并返回一个迭代器的迭代器。然后您可以选择将内部和外部迭代器都收集到Vecs:

        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

        【讨论】:

          【解决方案4】:

          slices 已有一个方法:

          pub fn chunks(&amp;self, chunk_size: usize) -&gt; Chunks&lt;'_, T&gt;

          从切片的开头开始,一次返回一个遍历切片的chunk_size 元素的迭代器。 块是切片并且不重叠。如果chunk_size不分割分片的长度,那么最后一个chunk就没有长度chunk_size

          还有chunks_mut 表示可变性,还有chunks_exactchunks_exact_mut 如果最后一个块必须遵守大小n,还有不安全的as_chunks_unchecked 以防我们假设没有余数,看下面的例子:

          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);
          }
          

          使用切片而不是向量有一些benefits,特别是避免了复制的开销。

          【讨论】:

          • 你不应该直接跳转到as_chunks_unchecked而不首先使用as_chunksarray_chunks
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-17
          • 2021-03-26
          • 2019-07-29
          • 1970-01-01
          • 2018-08-23
          • 1970-01-01
          相关资源
          最近更新 更多