如何编辑子数组中的值
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 数组的元素类型限制为 值类型 或 字符串.
我无法理解 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 数组的元素类型限制为 值类型 或 字符串.