2012-03-22 45 views
10

所以我们可以说我有这个数组:在Powershell中,如何检查一个数组中的所有项是否存在于第二个数组中?

$requiredFruit= @("apple","pear","nectarine","grape") 

而且我有第二个阵列称为$fruitIHave。我如何检查$fruitIHave是否有$requiredFruit中的所有内容。只要$requiredFruit中的所有内容都存在,$fruitIHave中是否有更多项目并不重要。

我知道我可以迭代列表,但这似乎效率低下,有没有一个内置的方法来做到这一点?

回答

24

你尝试比较,对象:

$requiredFruit= @("apple","pear","nectarine","grape") 
$HaveFruit= @("apple","pin","nectarine","grape") 
Compare-Object $requiredFruit $haveFruit 
InputObject             SideIndicator 
-----------             ------------- 
pin               => 
pear              <= 

Compare-Object $requiredFruit $haveFruit | where {$_.sideindicator -eq "<="} | % {$_.inputobject} 
pear 
1

不正是 “内置”,而是:

[regex] $RF_regex = ‘(?i)^(‘ + (($requiredFruit |foreach {[regex]::escape($_)}) –join “|”) + ‘)$’ 

($fruitIHave -match $RF_regex).count -eq $requiredFruit.count 

这就产生了从$ requiredFruit的元素交替的正则表达式。与$ fruitIHave匹配,它将返回所有匹配的项目。如果$ fruitIhave可能具有相同水果的重复项,则可能需要在计数之前通过get-unique运行匹配结果。它可能比遍历列表中的单个比较要慢,但是一旦你构建了正则表达式,它将非常有效地进行重复匹配。

0

无论如何,你将不得不遍历一个或两个数组。这里是一个班轮方法:

$hasAllRequiredFruit = ($requiredFruit | Where-Object { $fruitIHave -contains $_ }).Length -eq $requiredFruit.Length; 

一个foreach循环会更好,因为你可以为你找到所需的水果,缺少尽快停止迭代:

$hasAllRequiredFruit = $true; 
foreach ($f in $requiredFruit) 
{ 
    if ($fruitIHave -notcontains $f) 
    { 
     $hasAllRequiredFruit = $false; 

     break; 
    } 
} 
+1

@匿名懦夫:为什么downvote? – BACON 2016-01-15 18:22:42

11

如果你有数组:

$requiredFruit= @("apple","pear","nectarine","grape") 
$someFruit= @("apple","banana","pear","nectarine","orange","grape") 
$moreFruit= @("apple","banana","nectarine","grape") 

你可以得到一个布尔结果:

'Check $someFruit for $requiredFruit' 
-not @($requiredFruit| where {$someFruit -notcontains $_}).Count 

'Check $moreFruit for $requiredFruit' 
-not @($requiredFruit| where {$moreFruit -notcontains $_}).Count 

使用计数的数组防止单个值不匹配计算结果为假。例如:

# Incorrect result 
-not (0| where {(1,2) -notcontains $_}) 

# Correct result 
-not @(0| where {(1,2) -notcontains $_}).Count 

使用PowerShell v3,则可以使用select -first 1停止管道时,第一发现不匹配(在V2 select -first 1只允许一个通过对象,但管道的前面元素继续处理)。

-not @($requiredFruit| where {$moreFruit -notcontains $_}| select -first 1).Count 
相关问题