数组在哈希表中变成字符串

时间:2019-03-22 15:24:56

标签: arrays string powershell type-conversion

我有一个数组要返回给我,我正在使用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)
}

对于丢失的哈希表,这一定是简单的事情

3 个答案:

答案 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 )
}

}