Объединение и пересечение в PowerShell? - PullRequest
39 голосов
/ 23 декабря 2011

У меня есть массив объектов следующей структуры:

structure Disk
{
  int UID;
  String Computer;
}

На компьютере может быть набор общих дисков, а диск может быть общим для компьютеров.

Я хочувыяснить все диски, общие для всех компьютеров.Например, у меня есть компьютер A, B и C;Диски 1, 2 и 3. Дисковый массив: {1, A}, {1, B}, {2, A}, {2, B}, {2, C}, {3, A}.В результате я хочу получить диск 2, потому что он появляется на A, B и C.

Есть ли эффективный способ добиться этого?

С несколькими циклами foreach это достижимо,но определенно хочу лучшего способаЯ думаю о таких операциях, как пересечение, но не нашел этого в PowerShell.

Ответы [ 4 ]

71 голосов
/ 23 декабря 2011

Предполагая, что $arr - это массив, вы можете сделать так:

$computers = $arr | select -expand computer -unique
$arr | group uid | ?{$_.count -eq $computers.count} | select name

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

$a = (1,2,3,4)
$b = (1,3,4,5)
$a + $b | select -uniq    #union
$a | ?{$b -contains $_}   #intersection

Но для того, что вы спрашиваете, вышеприведенное решение работает хорошо и не совсем в отношении объединения и пересечения в стандартном определении терминов.

Обновление:

Я написал pslinq , который обеспечивает Union-List и Intersect-List, которые помогают достичь объединения и пересечения множества с Powershell.

13 голосов
/ 17 сентября 2013

Вы также можете сделать

$a = (1,2,3,4)
$b = (1,3,4,5)
Compare-Object $a $b -PassThru -IncludeEqual                   # union
Compare-Object $a $b -PassThru -IncludeEqual -ExcludeDifferent # intersection

Не работает, если $a равно нулю.

10 голосов
/ 05 ноября 2013

Для заданного вычитания (a - b):

$a | ?{-not ($b -contains $_)}

6 голосов
/ 01 февраля 2017

Хотя это не будет работать в самых ранних версиях, в более поздних версиях вы можете просто вызывать функции расширения .NET LINQ напрямую, например,

[system.linq.enumerable]::union([object[]](1,2,3),[object[]](2,3,4))

(без преобразования в какой-либо перечислимый тип, PowerShellвыдает ошибку «Не удается найти перегрузку».)

Это определенно работает в PowerShell V4 и V5 и определенно не работает в V2.У меня нет системы под рукой с V3.

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