Создание одноэлементного объекта массива Json с помощью PowerShell - PullRequest
2 голосов
/ 20 июня 2020

У меня есть созданный мной сценарий PowerShell 5.1, который импортирует файл CSV, манипулирует некоторыми данными, а затем преобразует объект данных в формат json с помощью командлета ConvertTo- Json в конце сценарий. Проблема, с которой я сталкиваюсь; в одном из моих полей мне нужно создать единый массив для свойства объекта в скобках. Итак, мне нужно, чтобы объект был похож на:

"PersonGroups":[
              {
                "Name":"test Name",
                "Id": 3433
              }
            ]

Вот вызов функции:

 $_.PersonGroups = Set-DataHash -InputObject $_

Ниже мой код, который у меня есть:

function Set-DataHash{
param(
    [psobject] $InputObject
)

$customObject = [psobject]@{
   Name = "Test"
   Id = 78888
}

$customArray = @($customObject)

return $customArray

}

Конечно, если у меня более одного объекта в массиве, он работает нормально; но поскольку это только один объект, ConvertTo- Json делает его единым объектом. Есть предложения, что делать?

Ответы [ 2 ]

3 голосов
/ 20 июня 2020

Как насчет:

 $_.PersonGroups = @(Set-DataHash -InputObject $_)

Вам не нужен «возврат».

2 голосов
/ 20 июня 2020

полезный ответ js2010 показывает, как решить проблему на стороне вызывающего , используя @(), оператор подвыражения массива. , вокруг вашего вызова функции Set-DataHash, чтобы возвращаемое значение было массивом .

Если вы хотите решить проблему из вашей функции , вы должны убедиться, что выводимый (возвращаемый) массив выводится в целом , как отдельный объект , что может быть достигнуто с помощью вспомогательный одноэлементный массив-оболочка , созданный с помощью (унарной формы) ,, оператора конструктора массива :

function Set-DataHash {
  param(
    [psobject] $InputObject
  )
  
  $customObject = [psobject] @{
    Name = "Test"
    Id   = 78888
  }
  
  # Wrap $customObject in an array with @(...), 
  # then *additionally* wrap this array in an *auxiliary* single-element array,
  # via `,` (array-construction operator).
  # Outputting this aux. array causes *it* to be enumerated, which therefore
  # outputs its only element as-is: the *original* array - see explanation below.
  # Note: I've omitted `return`, which is always optional.
  , @($customObject)
  
}

Пояснение :

По умолчанию - независимо от того, используете ли вы return или неявный вывод в функции или скрипте - вывод коллекции (включая массивы) вызывает ее элементы быть перечисляемым (иначе потоковым , развернутым или развернутым) ; то есть элементы выводятся один за другим в (невидимый, в данном случае) конвейер , через который вызывающий получает вывод.

  • В случае одиночной -элементной коллекции природа конвейера такова, что вызывающая сторона получает только этот единственный элемент - оболочка коллекции теряется.

  • В случае коллекции multi -element, указанная c исходная коллекция также теряется, а перечисленные элементы автоматически собираются в [object[]] array ).

Следовательно, упаковка коллекции, которую вы хотите вывести, целиком , поскольку отдельный объект требует доп. метод одноэлементного массива-оболочки, показанный выше; менее эффективной альтернативой является использование Write-Output с переключателем -NoEnumerate , который также предотвращает перечисление коллекции, переданной ему в качестве аргумента (не через конвейер).

Примечание:

  • В общем , для функций / скриптов, предназначенных для непосредственного вызова другими, лучше не выводить коллекции в целом, чтобы не нарушать общие ожидания потокового (перечисления) поведения в конвейере; в этом случае это вызывающий должен гарантировать, что собранный вывод является массивом через @(...), как показано в ответе js2010.

  • И наоборот, однако вывод коллекций в целом выполняется быстрее и позволяет выводить определенный тип коллекции c.

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