2011-12-22 99 views
31

我有以下结构的对象的数组:PowerShell中的联合和交集?

structure Disk 
{ 
    int UID; 
    String Computer; 
} 

计算机可以有一堆共享磁盘,和一个盘可以计算机之间共享。

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

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

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

+1

我建议将标题更改为“在PowerShell中联合,交叉和差异/设置减法”。所以我们将在一个地方进行所有的操作。 – 2016-04-25 09:15:16

+0

基于这里的问题和建议,我创建了一个PowerShell函数来为对象执行联合,交集和减法。检查出来:https://sqljana.wordpress.com/2015/09/23/perform-set-operations-union-intersection-minus-complement-using-powershell/ – 2016-12-02 16:35:30

回答

56

假设$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-ListIntersect-List,帮助实现建立工会和路口使用PowerShell。

+0

酷的东西,这些oneliners如何与密钥集合像哈希表? – Bastl 2015-11-18 12:06:52

+1

好帖子 - 应该有一个标准的数组库,提供这样的功能。 lodash for powershell .. – ferr 2016-03-02 20:25:51

+1

为了完整性,您可以使用 $ a |获得$ a和$ b之间的设置差异。 {{$ b -notcontains $ _} #difference – 2016-06-27 22:22:02

11

你也可以做

$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为空,但。

+1

可以向数组添加$ null。 $ a = 1,2,3,4,$ null – 2014-01-10 17:11:59

10

对于集相减( - B):

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

+7

还有-notcontains。 – 2014-01-10 17:08:59

3

虽然这不会在最早版本的工作,在新的版本你可以直接调用.NET的LINQ扩展功能,例如

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

(无投一些枚举类型,PowerShell中抛出一个“无法找到过载”错误。)

这绝对作品在PowerShell中V4和V5,绝对在V2没有。 V3没有系统。