如何在子数组中编辑值

时间:2018-08-24 16:04:54

标签: arrays powershell jagged-arrays

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

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

1 个答案:

答案 0 :(得分:3)

switch运算符实际上是作为LHS对数组进行的操作,是将该数组的元素原样用作结果数组的元素。

在当前情况下,这意味着 *$matrix[0]$matrix[1]都指向相同 5元素数组< / strong>由$matrix[2]个字符串组成,因此修改一个数组的元素将反映在所有3个"foo"元素中。

这种行为很可能是设计使然(请参阅底部),并且我不知道使用$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() }

请注意,索引到此二维数组中需要一个单个索引表达式和一个 list 索引;例如$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]


设计灵感

我只能推测一下设计意图,但我想尝试 no 尝试对恰好是LHS数组元素的 clone 集合进行尝试,因为不能保证可以克隆这样的集合 -更普遍的是,LHS数组的所有类型都是引用类型(字符串除外)的元素类型。

使用Lem数组元素为值类型 strings -这是最典型的情况-没问题,因为结果数组的元素将(有效)独立副本。

简而言之:要使用[0][1]进行可预测的数组复制,请将LHS数组的元素类型限制为值类型字符串