gpt4 book ai didi

rust - 如何高效地逐行遍历 `Vec>`?

转载 作者:行者123 更新时间:2023-11-29 08:07:14 30 4
gpt4 key购买 nike

我正在编写一个使用 Vec<Vec<T>> 的库类型以按列优先顺序存储数据(每个内部 Vec 代表一列)。用户可以创建 Vec<Vec<T>>具有任何行和列长度,但所有列都被限制为相同的长度。

有时我需要高效地遍历 Vec<Vec<T>>按行。我不想更改数组类型,因为大多数时候我需要“按列向量”迭代(一次一个完整的列向量)。

除非我遗漏了什么,Iterator::zip不是一个选项,因为我事先不知道列向量的数量。 Itertools::izipItertools::multizip也不可行。

这是我的示例代码:

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 吗? vector 在开始迭代之前避免在每个周期进行分配,还是编译器会处理这个优化?自己找到它的最简单方法是什么?

是否有更高效/惯用的解决方案?

最佳答案

一旦有了迭代器向量,如何将其转换为向量迭代器?

有两种创建迭代器的方法:使用现有的迭代器适配器或实现自定义迭代器。

让我们采用第二种方法并定义一个采用迭代器向量的自定义迭代器类型:

struct DynamicZip<I>
where I: Iterator {
iterators: Vec<I>
}

然后让我们提供一个迭代器实现:

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]

关于rust - 如何高效地逐行遍历 `Vec<Vec<T>>`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54756166/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com