如何有效地逐行迭代`Vec<Vec<T>`? [英] How do I efficiently iterate through a `Vec<Vec<T>>` row by row?
问题描述
我正在编写一个库,它使用 Vec
类型以列优先顺序存储数据(每个内部 Vec
代表一列).用户可以创建具有任何行和列长度的 Vec
,但所有列都被限制为相同的长度.
I am writing a library which employs a Vec<Vec<T>>
type to store data in column-major order (each inner Vec
represents a column). The user can create a Vec<Vec<T>>
with any row and column length but all columns are constrained to be the same length.
有时我需要按行高效地遍历 Vec
.我不想更改数组类型,因为大多数时候我需要按列向量"(一次一个完整的列向量)进行迭代.
I need to sometimes efficiently iterate through the Vec<Vec<T>>
by row. I would like to not change the array type because most of the time I need to iterate "by column vector" (one full column vector at a time).
除非我遗漏了什么,否则 Iterator::zip
不是一个选项,因为我事先不知道列向量的数量.Itertools::izip
和 Itertools::multizip
也不可行.
Unless I am missing something, Iterator::zip
is not an option because I do not know the number of column vectors in advance. Itertools::izip
and Itertools::multizip
are also not viable.
这是我的示例代码:
let array = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
let mut iterators: Vec<_> = array.iter().map(|x| x.iter()).collect();
for _ in 0..array[0].len() {
let values: Vec<_> = iterators.iter_mut().map(|x| x.next().unwrap()).collect();
dbg!(values);
}
我应该在开始迭代之前定义一个可变的 values
向量以避免在每个周期进行分配,还是编译器会处理这种优化?自己找到最简单的方法是什么?
Should I define a mutable values
vector before starting the iterations to avoid allocations at each cycle, or will the compiler take care of this optimization anyway? What is the easiest method to find it myself?
是否有更有效/惯用的解决方案?
Are there more efficient / idiomatic solutions?
推荐答案
一旦我有了迭代器向量,我该如何将其转换为向量迭代器?
有两种方法可以创建迭代器:使用现有的迭代器适配器或实现自定义迭代器.
Once I have a vector of iterators, how can I convert it to an iterator of vectors?
There are two ways to create an Iterator: to use an existing iterator adapter or to implement a custom Iterator.
让我们采用第二种方法并定义一个采用迭代器向量的自定义迭代器类型:
Let's take the second approach and define a custom Iterator type that takes a vector of iterators:
struct DynamicZip<I>
where I: Iterator {
iterators: Vec<I>
}
让我们提供一个迭代器实现:
and let's provide an Iterator implementation:
impl<I, T> Iterator for DynamicZip<I>
where I: Iterator<Item = T> {
type Item = Vec<T>;
fn next(&mut self) -> Option<Self::Item> {
let output: Option<Vec<T>> = self.iterators.iter_mut().map(|iter| iter.next()).collect()
output
}
}
我们就完成了!
fn main() {
let array = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
let iterators: Vec<_> = array.into_iter().map(|v| v.into_iter()).collect();
let dz = DynamicZip { iterators: iterators };
// use the Iterator type we just defined
for column in dz {
println!("{:?}", column)
}
}
将产生输出
[1, 4, 7]
[2, 5, 8]
[3, 6, 9]
这篇关于如何有效地逐行迭代`Vec<Vec<T>`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!