[英]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上沒有直接的這種輔助方法。 但是,有兩種主要方法可以做到:
使用[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]
使用板條箱itertools
的Itertools::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.