在Powershell中,如何检查一个数组中的所有项是否都存在于第二个数组中?

时间:2012-03-22 01:19:09

标签: arrays powershell

所以我想说我有这个数组:

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

我给了第二个名为$fruitIHave的数组。如何检查$fruitIHave是否包含$requiredFruit中的所有内容。只要$fruitIHave中的所有内容都存在,$requiredFruit中的项目是否还有其他内容都无关紧要。

我知道我可以遍历列表,但这似乎效率低下,是否有内置的方法来执行此操作?

4 个答案:

答案 0 :(得分:25)

你尝试比较对象:

$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 :(得分:14)

如果您有阵列:

$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

使用数组的计数可以防止不匹配的单个值计算为False。例如:

# 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

答案 2 :(得分:1)

不完全&#34;内置&#34;但是:

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

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

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

答案 3 :(得分:1)

无论如何,您将不得不迭代一个或两个数组。这是一个单线方法:

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

foreach循环会更好,因为您可以在找到缺少的所需水果后立即停止迭代:

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

       break;
    }
}