【问题标题】:In Powershell how can I check if all items from one array exist in a second array?在 Powershell 中,如何检查一个数组中的所有项目是否存在于第二个数组中?
【发布时间】:2012-03-22 21:34:08
【问题描述】:

假设我有这个数组:

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

我得到了第二个数组$fruitIHave。如何检查$fruitIHave 是否包含$requiredFruit 中的所有内容。 $fruitIHave 中是否有更多项目无关紧要,只要 $requiredFruit 中的所有内容都存在即可。

我知道我可以只遍历列表,但这似乎效率低下,是否有内置方法可以做到这一点?

【问题讨论】:

    标签: arrays powershell


    【解决方案1】:

    你试试比较对象:

    $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
    

    【讨论】:

    • 相同而不需要 where 过滤器:Compare-Object $requiredFruit $HaveFruit -PassThru -ExcludeDifferent -IncludeEqual
    • @Dirk 不起作用,这将返回 $requiredFruit 和 $haveFruit 的交集,而不是 $requiredFruit 中 $haveFruit 的补码。然而这会起作用:$requiredFruit.Where{$_ -notin $haveFruit}
    【解决方案2】:

    如果你有数组:

    $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
    

    【讨论】:

      【解决方案3】:

      不完全是“内置”,而是:

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

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

      【讨论】:

        【解决方案4】:

        一种或另一种方式,您将不得不遍历一个或两个数组。这是一种单行方法:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-04
          • 1970-01-01
          • 2021-10-26
          • 2016-07-27
          • 1970-01-01
          相关资源
          最近更新 更多