2

我正在学习中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等价物(即:我找不到它),用向量向量实现类似行为的最佳方法是什么?

4

2 回答 2

2

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

此版本适用于任何可克隆值(包括数字)。我们迭代子向量,并为每个子向量调用一个get方法,该方法要么产生向量的元素,要么Some(&e)超出None范围。

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

collect然后与 一起使用Iter<Option<T>>,并且它方便地将其转入Option<Vec<T>>,即None如果迭代器中有一些Nones 则返回(这意味着某些数组没有足够大的大小),或者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()
}
于 2020-05-07T15:05:59.077 回答
2

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()
}

操场

于 2020-05-08T07:59:22.463 回答