如何编辑子数组中的值

How to edit value in a sub array

我无法理解 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

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

作为 LHS,* 运算符实际上对数组所做的是使用该数组的元素 as-is 作为元素结果数组。

在手头的例子中,这意味着$matrix[0]$matrix[1]$matrix[2]都指向相同的 5 元素数组 "foo" 个字符串组成,因此修改一个数组的元素将反映在所有 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'
  }
}

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


设计思路:

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

对于值类型字符串的LHS数组元素——这是更典型的情况——没有问题,因为结果数组的元素将(有效地)是独立的副本。

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