簡體   English   中英

是否可以使用迭代器將向量分成 10 個一組?

[英]Is it possible to split a vector into groups of 10 with iterators?

我已經let my_vec = (0..25).collect::<Vec<_>>()並且我想將my_vec分成 10 個組的迭代器:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
[20, 21, 22, 23, 24, None, None, None, None, None];

是否可以使用 Rust 中的迭代器來做到這一點?

Iterator trait上沒有直接的這種輔助方法。 但是,有兩種主要方法可以做到:

  1. 使用[T]::chunks()方法(可以直接在Vec<T>上調用)。 然而,它有一個細微的區別:它不會產生None ,但最后一次迭代會產生一個更小的切片。

    示例

     let my_vec = (0..25).collect::<Vec<_>>(); for chunk in my_vec.chunks(10) { println!("{:02?}", chunk); }

    結果:

     [00, 01, 02, 03, 04, 05, 06, 07, 08, 09] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] [20, 21, 22, 23, 24]
  2. 使用板條箱itertoolsItertools::chunks()方法 這個 crate 擴展了標准庫中的Iterator trait,因此這個chunks()方法適用於所有迭代器! 請注意,為了通用,用法稍微復雜一些。 這與上述方法具有相同的行為:在最后一次迭代中,塊將更小而不是包含None s。

    示例

     extern crate itertools; use itertools::Itertools; for chunk in &(0..25).chunks(10) { println!("{:02?}", chunk.collect::<Vec<_>>()); }

    結果:

     [00, 01, 02, 03, 04, 05, 06, 07, 08, 09] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] [20, 21, 22, 23, 24]

您可以僅使用標准庫實現與Lukas Kalbertodt 的 itertools 示例類似的解決方案:

let my_vec = (0..25).collect::<Vec<_>>();

let mut my_values = my_vec.into_iter().peekable();

while my_values.peek().is_some() {
    let chunk: Vec<_> = my_values.by_ref().take(10).collect();
    println!("{:?}", chunk);
}

結果:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[20, 21, 22, 23, 24]

如果您實際上不需要每個塊的Vec ,您可以省略collect調用並直​​接對by_ref創建的迭代器進行by_ref

另見:

我從 Python 改編來獲得像 Python 的itertools提供的groupby()效果的一個技巧是使用.zip().skip().step_by()組合兩個或多個迭代器。 這種方法可以產生 10 人一組,但在代碼庫中看到會很不美觀。 但如果您需要小團體,這可能沒問題。

Rust 確實有帶有.group_by()itertools板條箱,但根據情況,這並不總是可用 - 例如,向 HackerRank 等網站提交 Rust 解決方案。

fn main()
{
    let a = "Hello, World!";

    println!("{:?}", a.chars().step_by(2).zip(
                         a.chars().skip(1).step_by(2) 
                     ).collect::<Vec<_>>());
}

輸出:

[('H', 'e'), ('l', 'l'), ('o', ','), (' ', 'W'), ('o', 'r'), ('l', 'd')]

其中n是壓縮迭代器的數量, .step_by的值對於所有迭代器都是n ,而.skip()的值將取決於迭代器在鏈中的位置; 第一個迭代器將跳過 0,下一個 1,等等。

您可以通過這種方式鏈接任意數量的迭代器,但是在第三個之后它開始看起來有點復雜和丑陋。 在這種情況下,也許可以考慮將迭代器收集到Vec並使用其.chunks()方法。 或者,如果可以,請使用itertools板條箱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM