我有一个数组要返回给我,我正在使用foreach进行逐步操作,我想在哈希表中使用该数组每个成员的一个元素,该哈希表将转换为json对象。当我将元素添加到Powershell数组对象中,然后将其添加到哈希中时,字符串将被合并,而不是作为数组添加。
规格
"destinationInterclusterLifIps": [
"172.31.5.119",
"172.31.15.103"
]
实际回报:
"destinationInterclusterLifIps": [
"172.31.33.150172.31.42.41"
],
构建数组
if(!$destinationInterclusterLifIps){
$destinationInterclusterLifIps = @()
foreach($record in $interclusterIpInfo.peerInterClusterLifs){
$destinationInterclusterLifIps += $record.address
}
}
哈希表
$body = @{
destinationInterclusterLifIps = @($destinationInterclusterLifIps)
}
对于丢失的哈希表,这一定是简单的事情
答案 0 :(得分:2)
您的代码本身不能解释症状,但是your own answer暗示了一个有趣的陷阱,值得探讨:
默认情况下,PowerShell变量可以接受任何类型的值,并且可以随时分配不同类型的值:
$var = 42 # $var now contains an [int]
# ...
$var = 'hi' # $var now contains a [string]
但是,您可以类型约束变量,在这种情况下,它们只能接受该类型的值-或可以自动为的值转换为该类型(PowerShell在进行自动转换时非常灵活):
# Create a type-constrained variable.
[int] $var = 42 # $var now contains an [int] AND is locked into storing [int]s
# Try to assign a [string] that CANNOT be converted to an [int]
$var = 'hi' # FAILS: 'Cannot convert value "hi" to type "System.Int32"...'
# Try to assign a [string] that CAN be converted to an [int]
$var = ' 42 ' # OK - string was converted; $var now contains [int] 42
通常(但不一定),参数变量是类型受限的,作为脚本或函数的已声明参数列表的一部分。
如果您稍后通过分配新的值来重用类型受限的参数变量,则它将强制执行其原始类型,如上所述。
您情况下最可能的解释是,您的 $destinationInterclusterLifIps
被声明为类型受限的[string] $destinationInterclusterLifIps
参数,在这种情况下,后来的试图分配一个 array 导致该数组的隐式字符串化 ;用一个简单的例子来说明:
function foo {
param(
# Type-constrained parameter.
[string] $destinationInterclusterLifIps
)
# ...
# Try to assign an *array*:
# Instead of storing an array, the [string] type constraint
# converts the array to a *single string*, as a space-separated list of
# its elements.
$destinationInterclusterLifIps = 1, 2, 3
# Output the value.
$destinationInterclusterLifIps
}
# Call the function (no argument needed)
foo
这将输出:
1 2 3
,即,数组转换为 string ,作为其元素的空格分隔列表。 (一个数组将逐个元素地逐行打印)。
请注意,因此,您的问题与哈希表的使用及其向JSON的转换无关-这正是您偶然发现问题的地方。
可选阅读:修改/删除变量的类型约束:
稍后可以重新创建类型为 的受类型约束的变量;例如:
[int] $var = 42; [string] $var = 'hi'
您可以使用Remove-Variable
有效地删除类型约束,方法是先删除变量,然后不受约束地重新创建变量,如TheIncorrigible1建议-
{{ 1}}-您可以使用[int] $var = 42; Remove-Variable var; $var = 'hi'
作为快捷方式,因为对[object] $var = 'hi'
的类型约束等同于不约束值。
[object]
包含变量的属性,类型约束属性存储为(Get-Variable var).Attributes
实例。如果您不关心删除 all 属性,则删除类型约束的另一种简单方法(尽管晦涩难懂)是使用[System.Management.Automation.ArgumentTypeConverterAttribute]
。
答案 1 :(得分:0)
好像我与变量有冲突。也许是因为它也被用作参数。将变量设置为任何其他名称可以解决此问题。
if(!$sourceInterclusterLifIps){
$InterclusterIPSource = @()
foreach($record in $interclusterIpInfo.interClusterLifs){
$InterclusterIPSource += $record.address
}
} else {
$InterclusterIPSource = $sourceInterclusterLifIps
}
答案 2 :(得分:-1)
尝试将ArrayList与.add()一起使用,它应该做您想要的事情。
$destinationInterclusterLifIps = New-Object System.Collections.ArrayList
if(!$destinationInterclusterLifIps){
$destinationInterclusterLifIps = @()
foreach($record in $interclusterIpInfo.peerInterClusterLifs){
$destinationInterclusterLifIps.add( $record.address )
}
}