【问题标题】:How to edit value in a sub array如何编辑子数组中的值
【发布时间】:2018-08-24 16:04:54
【问题描述】:

我无法理解 powershell 中的这种行为:

$PSVersionTable.PSVersion

""

$matrix =, @(, @("foo") * 5) * 3

$matrix[0][1] = "bar"

foreach($subArray in $matrix){
    Write-Host $($subArray[1])
}

使用这个脚本,我正在初始化一个由 3 个数组组成的数组,每个数组包含 5 个字符串“foo”。

我想将第一个数组的第二个元素设置为“bar”,每个数组都会受到影响:

# Returned :
Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      15063  1155    

bar
bar
bar

这是一个错误还是我误解了数组的工作原理?

【问题讨论】:

    标签: arrays powershell jagged-arrays


    【解决方案1】:

    * 运算符事实上对 LHS 数组所做的就是将该数组的元素按原样用作结果数组的元素。

    在本例中,这意味着$matrix[0]$matrix[1]$matrix[2]都指向由@组成的相同5元素数组 987654325@ 字符串,因此修改一个数组的元素将反映在所有 3 个$matrix 元素中。

    这种行为可能是设计使然(见底部),我不知道使用 * 语法的简洁解决方法。

    一个可行的解决方法是:

    # Note: The (...) around the arrays to replicate aren't strictly needed,
    #       because `,` has higher precedence than `*`, but were added for
    #       readability.
    $nestedArrayTemplate = (, 'foo') * 5
    $matrix = (, @()) * 3  # (, $null) * 3 would work too
    
    for ($i=0; $i -lt $matrix.Count; ++$i) { $matrix[$i] = $nestedArrayTemplate.Clone() }
    

    顺便说一句:上面创建了一个锯齿状数组,而不是一个矩阵(二维数组)。以下是创建真正的二维数组的方法:

    $matrix = [string[,]]::new(3, 5) # PSv4-: New-Object string[] 3, 5
    for ($row = 0; $row -lt $matrix.GetLength(0); ++$row) {
      for ($col = 0; $col -lt $matrix.GetLength(1); ++$col ){
        $matrix[$row, $col] = 'foo'
      }
    }
    

    注意,索引到这个二维数组需要一个单个索引表达式和一个列表索引;例如,[0, 1] 而不是 [0][1]


    设计思考

    我只能推测设计意图,但我认为 没有 尝试克隆恰好是 LHS 数组元素的集合,因为有不保证此类集合可以被克隆 - 这同样适用于 LHS 数组的所有元素类型引用类型(字符串除外)。

    使用 值类型字符串 的 LHS 数组元素 - 这是更典型的情况 - 没有问题,因为生成的数组元素将(有效地)独立副本。

    简而言之:对于 * 的可预测数组复制,将 LHS 数组的元素类型限制为 值类型字符串

    【讨论】:

    • 非常感谢。你对我的了解超出了预期。我只想要一个锯齿状数组,因为我不知道尽可能内置的真实矩阵。
    • @Alsatian:很高兴听到这个消息;我的荣幸。 PowerShell 本身不支持原生多维数组,但凭借其对底层 .NET 框架的近乎无限访问权限,您可以在 PowerShell 中执行的操作几乎没有限制——如果不考虑性能的话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-17
    • 2021-12-15
    相关资源
    最近更新 更多