PowerShell中的联盟和交集?

use*_*554 42 arrays powershell

我有一系列具有以下结构的对象:

structure Disk
{
  int UID;
  String Computer;
}
Run Code Online (Sandbox Code Playgroud)

计算机可以具有一堆共享磁盘,并且可以在计算机之间共享磁盘.

我想找出所有计算机常用的所有磁盘.例如,我有计算机A,B和C; 磁盘阵列1,2和3.磁盘阵列为{1,A},{1,B},{2,A},{2,B},{2,C},{3,A}.我想要的结果应该是磁盘2,因为它出现在A,B和C上.

有没有有效的方法来实现这一目标?

有多个foreach循环,它是可以实现的,但绝对我想要一个更好的方法.我正在考虑像交集这样的操作,但是在PowerShell中没有找到它.

man*_*lds 73

假设$arr是数组,你可以这样做:

$computers = $arr | select -expand computer -unique
$arr | group uid | ?{$_.count -eq $computers.count} | select name
Run Code Online (Sandbox Code Playgroud)

一般来说,我会在Powershell中接近union和intersection,如下所示:

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

但是对于你所要求的,上述解决方案效果很好,而不是关于术语标准定义中的并集和交集.

更新:

我已经写pslinq提供Union-ListIntersect-List这样才有利于实现并集和交集使用PowerShell.

  • 为了完整起见,您可以使用$ a |获得$ a和$ b之间的集合差。?{$ b-不包含$ _} #difference (2认同)

sha*_*p00 13

你也可以

$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
Run Code Online (Sandbox Code Playgroud)

如果$a为null 则不起作用.


ner*_*ist 12

对于集合减法(a - b):

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

  • 还有-notcontains. (8认同)
  • Narthan 可以节省人们的时间,下次再写出来:) ``$a | ?{$b - 不包含 $_}`` (2认同)

unb*_*bob 6

虽然这在最早的版本中不起作用,但在更新的版本中,您可以直接调用.NET LINQ扩展函数,例如

[system.linq.enumerable]::union([object[]](1,2,3),[object[]](2,3,4))
Run Code Online (Sandbox Code Playgroud)

(如果没有强制转换为某种可枚举类型,PowerShell会抛出"无法找到重载"错误.)

这绝对适用于PowerShell V4和V5,绝对不适用于V2.我没有V3的系统.