Как получить список определенного поля из списка объектов в powershell

Я новичок в скриптах PowerShell. Извиняюсь, если я пропускаю что-то простое.

Допустим, у меня есть объект под названием object это поле называется field, Теперь пусть будет список этих объектов.

Как бы получить список полей в том же порядке?

В питоне это будет:

list_of_objects = [o1, o2, o3]
list_of_fields = [i.field for i in list_of_object]

2 ответа

Решение

PowerShell хорош и не так хорош, потому что он разворачивает коллекции для вас, и иногда это может скрывать, что он маскирует элементы элементов. Когда вы используете $parents.item, вы получаете доступ к методу массива и пытаетесь получить доступ к его элементам (которых там нет, поэтому PowerShell дает вам $null):

Item           ParameterizedProperty System.Object IList.Item(int index) {get;set;}

Вы можете преодолеть это с помощью метода, которым я поделился в комментариях, чтобы перебрать каждого члена и избежать этой маскировки:

$list = $parents | ForEach-Object -MemberName item
$list.registration.parentCompoundNumber

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

$list = $parents | Select-Object -ExpandProperty item

или раскручиваем сами

# you could directly assign the outputs of a `foreach` loop to a variable by
# removing these comments (<##>)
<# $items = #> 
  foreach ($parent in $parents) {
    $parent.item.registration.parentCompoundNumber
  }

Чтобы увидеть, когда происходит эта маскировка, рассмотрим пример, в котором используется оператор унарного массива:

, @('a', 'b', 'c') | Get-Member

Это позволит вам наблюдать за упаковочным массивом или членами коллекции.

В дополнение к полезному ответу TheIncorrigible1:

Связанный ответ содержит жизнеспособные обходные пути для конфликтов имени участника; Позвольте мне добавить альтернативу PSv4+, которая более краткая и быстрая, чем конвейерный подход:

$parent.ForEach('item').registration.parentCompoundNumber

С использованием .ForEach() метод массива с именем свойства ('item') однозначно нацеливается на элементы.


Чтобы предложить небольшое переосмысление объяснения, почему требуется обходной путь:

  • Перечисление членов PowerShell по существу относится к $someCollection.someProp как будто ты написал foreach ($element in $someCollection) { $element.someProp }; то есть элементы $someCollection перечислены, и элементы " .someProp Значения свойств возвращаются в виде массива.

    • Примечание. Как и в конвейере, если в коллекции есть только один элемент, значение свойства этого элемента возвращается как есть, а не как одноэлементный массив.
  • Однако, если сам тип коллекции имеет член с именем someProp используется, и перечисление не происходит; то есть члены уровня коллекции скрывают (имеют приоритет над) элементы уровня элемента с тем же именем - и это то, что случилось с .Item в твоем случае.

    • Если есть сомнения, выход $someCollection.someProp интерактивно / во время отладки, чтобы увидеть, что он оценивает.
Другие вопросы по тегам