Союз и пересечение в 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.
Ответы
Ответ 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.