Как сгруппировать массивы в Powershell? - PullRequest
2 голосов
/ 29 апреля 2020

Каков простой и эффективный способ преобразования массива с помощью PowerShell? Исходный массив имеет два свойства Number и Color.

Number  Color
1       Red
2       Red
3       Red
4       Red
5       Blue
6       Blue
7       Green
8       Green
9       Green

Выходной массив должен выглядеть так:

Color   Number
Red     1,2,3,4
Blue    5,6
Green   7,8,9

Ответы [ 2 ]

4 голосов
/ 29 апреля 2020
# Input objects.
$objects = @'
Number,Color
1,Red
2,Red
3,Red
4,Red
5,Blue
6,Blue
7,Green
8,Green
9,Green
'@ | ConvertFrom-Csv

$objects |
  Group-Object Color |
    Select-Object @{ n='Color'; e='Name'}, @{ n='Number'; e={ $_.Group.Number } }

Приведенные выше значения:

Color Number
----- ------
Blue  {5, 6}
Green {7, 8, 9}
Red   {1, 2, 3, 4}

Примечание. В связи с тем, как работает Group-Object, значения Color сортируются в алфавитном порядке в выводе.

См. Также:

1 голос
/ 29 апреля 2020

Если добавить @ mklement0's отличный ответ, используя Group-Object, мы также можем сгруппировать элементы в System.Collections.Hashtable, добавив переключатель -AsHashTable. Для итерации ключей и значений хеш-таблицы мы должны использовать System.Collections.Hashtable.GetEnumerator.

$objects = @'
Number,Color
1,Red
2,Red
3,Red
4,Red
5,Blue
6,Blue
7,Green
8,Green
9,Green
'@ | ConvertFrom-Csv

$ht = $objects | Group-Object -Property Color -AsHashTable

$ht.GetEnumerator() | 
    Select-Object @{Name="Color";Expression={$_.Key}}, @{Name="Number";Expression={$_.Value | Select-Object -ExpandProperty Number}}

Вывод:

Color Number
----- ------
Green {7, 8, 9}
Red   {1, 2, 3, 4}
Blue  {5, 6}

Если мы хотим отсортировать ваш результат по Number, мы можем использовать Sort-Object для сортировки по первому числу :

$ht.GetEnumerator() | 
    Select-Object @{Name="Color";Expression={$_.Key}}, @{Name="Number";Expression={$_.Value | Select-Object -ExpandProperty Number}} |
        Sort-Object @{Expression={$_.Number[0]}}

Или используйте System.Collections.Specialized.OrderedDictionary для создания упорядоченного хэш-таблицы массивов и поддержания порядка вставки ключей:

$ht = [ordered]@{}
foreach ($object in $objects) {
    if (-not ($ht.Keys -contains $object.Color)) {
        $ht[$object.Color] = @()
    }
    $ht[$object.Color] += $object.Number
}

$ht.GetEnumerator() | 
    Select-Object @{Name="Color";Expression={$_.Key}}, @{Name="Number";Expression={$_.Value}} 

, который выдаст следующее :

Color Number
----- ------
Red   {1, 2, 3, 4}
Blue  {5, 6}
Green {7, 8, 9}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...