Массив превращается в строку в хэш-таблице - PullRequest
0 голосов
/ 22 марта 2019

У меня есть возвращаемый массив, к которому я обращаюсь через foreach, я хочу использовать один элемент каждого члена этого массива в хэш-таблице, который будет преобразован в объект json.Когда я добавляю элемент в объект массива powershell, а затем добавляю его в хеш, строки объединяются, а не добавляются как массивы.

Spec

"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 ]

2 голосов
/ 22 марта 2019

Ваш код не объясняет симптом, но ваш собственный ответ намекает на интересную ловушку , которую стоит изучить:

  • По умолчанию переменная 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 параметр , и в этом случае более поздняя попытка присвоить массив привела к неявная строковая этого массива ;для иллюстрации на простом примере:

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

, то есть массив, преобразованный в строку , как разделенный пробелами списокего элементы.(Массив будет выводить элемент за элементом, каждый на отдельной строке).

Обратите внимание, что ваша проблема была поэтому не связана с использованием хеш-таблицы и ее преобразованием в JSON - это именно то, гдевы случайно заметили проблему.


Необязательное чтение: изменение / удаление ограничения типа переменной :

Возможно позднее воссоздать переменную с ограничением типас другим типом;например:

[int] $var = 42; [string] $var = 'hi'

Хотя вы можете использовать Remove-Variable для эффективного удаления ограничения типа, сначала удалив переменную, а затем воссоздайте ее без ограничений, как подсказывает TheIncorrigible1 -
[int] $var = 42; Remove-Variable var; $var = 'hi' - вы можете использовать [object] $var = 'hi' в качестве ярлыка, поскольку ограничение типа [object] равносильно , а не , ограничивающему значение.

(Get-Variable var).Attributes содержитатрибуты переменной и атрибут ограничения типа сохраняются как экземпляр [System.Management.Automation.ArgumentTypeConverterAttribute].Если вас не беспокоит удаление всех атрибутов, другой простой, хотя и неясный, вариант для удаления ограничения типа - использовать (Get-Variable var).Attributes.Clear().

0 голосов
/ 22 марта 2019

Похоже, у меня был конфликт с переменной.Может быть, потому что он также используется в качестве параметра.Установка переменной для любого другого имени устраняет проблему.

if(!$sourceInterclusterLifIps){
    $InterclusterIPSource =  @()
    foreach($record in $interclusterIpInfo.interClusterLifs){
        $InterclusterIPSource += $record.address
    }
} else {
    $InterclusterIPSource = $sourceInterclusterLifIps
}
0 голосов
/ 22 марта 2019

попробуйте использовать ArrayList с .add (), он должен делать то, что вы хотите.

$destinationInterclusterLifIps = New-Object System.Collections.ArrayList
if(!$destinationInterclusterLifIps){
$destinationInterclusterLifIps =  @()
foreach($record in $interclusterIpInfo.peerInterClusterLifs){
    $destinationInterclusterLifIps.add( $record.address )
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...