Как получить список определенного поля из списка объектов в 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
интерактивно / во время отладки, чтобы увидеть, что он оценивает.
- Если есть сомнения, выход