Подтвердить что ты не робот

Союз и пересечение в PowerShell?

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

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.

4b9b3361

Ответ 1

Предполагая, что $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

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

Update:

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

Ответ 2

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

$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 имеет значение null.

Ответ 3

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

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

Ответ 4

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

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

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

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