【问题标题】:Implementing PHP array_column in Rust在 Rust 中实现 PHP array_column
【发布时间】:2020-08-22 20:39:56
【问题描述】:

我正在学习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]。如果我将 0 更改为 1,我会得到 [2,2,2,2] 等等。

由于 Rust 中没有 array_column 等效项(即:我找不到它),用向量向量实现类似行为的最佳方法是什么?

【问题讨论】:

  • 我假设 PHP 对内存没有任何魔力,因为子数组可能放置在内存的不同部分。所以只需创建一个容量为records 大小的新向量,然后迭代外部向量中的每个元素,并在结果中添加一个subvector[k] 元素。您还应该检查每个 subvector 的大小是否大于 k
  • @AlexLarionov:感谢您的评论!基本上,你的解决方案就是我的解决方案,但当我发现你可以做这样的事情时,我想我错过了一些大事:let zipped: Vec<_> = a.iter().zip(b.iter()).collect();(这只适用于 2 个向量,对我来说还不够)。不知道PHP底层是做什么的,但是array_column的实现确实很快

标签: rust array-column


【解决方案1】:

我决定使用迭代器,就像您在 cmets 中尝试的那样。

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

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

collect 然后与Iter<Option<T>> 一起工作,它可以方便地将它转入Option<Vec<T>>,即如果一些Nones 在迭代器中,它会返回None(这意味着一些数组没有足够大size),或者返回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()
}

【讨论】:

    【解决方案2】:

    Alex version 很好,但是你也可以使用引用来概括它,所以项目不需要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()
    }
    

    Playground

    【讨论】:

    • 没错,但作为旁注,当函数的结果存在于某处时,您不能删除源数组。那时可能使用不方便
    • @AlexLarionov,好吧,编译器会为你检查,这样你以后也可以在需要时明确克隆。
    猜你喜欢
    • 2021-03-31
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 2015-01-28
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    相关资源
    最近更新 更多