在Rust中实现PHP array_column



我正在学习Rust,但我找不到这个问题的答案。

在PHP中,有array_column方法,它是这样工作的:

给定一个数组数组(这将是Rust中的一个向量向量(:

$records = [
[1,2,3],
[1,2,3],
[1,2,3],
[1,2,3]
];

如果我想得到一个包含内部数组的所有第一个元素("列"(的数组,我可以做:

$column = array_column($records, 0);

例如,通过这种方式,我得到了[1,1,1,1]。如果我用1改变0,我得到[2,2,2,2],依此类推

既然Rust中没有array_column等价物(也就是说:我找不到它(,那么用矢量实现类似行为的最佳方法是什么?

我决定使用迭代器,正如您在评论中所尝试的那样。

此版本适用于任何可克隆值(包括数字(。我们对子向量进行迭代,并为每个子向量调用get方法,如果我们要求越界,该方法会产生向量Some(&e)None的元素。

然后,and_then接受来自get的值,如果是None,则返回None,否则,如果是Some(&e),则返回Some(e.clone()),即我们克隆该值(因为我们只有对get的值的引用,所以我们无法存储它,我们必须复制该值(。

然后collectIter<Option<T>>一起工作,它方便地将其转换为Option<Vec<T>>,即如果迭代器中有一些None(这意味着一些数组的大小不够大(,它将返回None,或者如果一切正常,则返回Some(Vec<T>)

fn main() {
let array = vec![
vec![1, 2, 3, 4],
vec![1, 2, 3, 4, 5],
vec![1, 2, 3, 4],
vec![1, 2, 3, 4],
];
let ac = array_column(&array, 0);
println!("{:?}", ac); // Some([1, 1, 1, 1])
let ac = array_column(&array, 3);
println!("{:?}", ac); // Some([4, 4, 4, 4])
let ac = array_column(&array, 4); // None
println!("{:?}", ac);
}
fn array_column<T: Clone>(array: &Vec<Vec<T>>, column: usize) -> Option<Vec<T>> {
array.iter()
.map( |subvec| subvec.get(column).and_then(|e| Some(e.clone())) )
.collect()
}

Alex版本很好,但您也可以使用引用对其进行概括,因此不需要将项目设为Clone:

fn array_column<'a, T>(array: &'a Vec<Vec<T>>, column: usize) -> Option<Vec<&'a T>> {
array.iter()
.map( |subvec| subvec.get(column) )
.collect()
}

游乐场

最新更新