2012-03-22 11 views
10

Así que vamos a decir que tengo esta matriz:En Powershell, ¿cómo puedo verificar si todos los elementos de una matriz existen en una segunda matriz?

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

Y me dio una segunda matriz llamada $fruitIHave. ¿Cómo puedo verificar que $fruitIHave tiene todo en $requiredFruit. No importa si hay más elementos en $fruitIHave siempre que todo en $requiredFruit esté allí.

Sé que podría simplemente iterar sobre la lista, pero parece ineficaz, ¿hay un método incorporado para hacer esto?

Respuesta

24

¿Trata de comparación a objetos :

$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

No exactamente "incorporado", sino:

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

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

que crea una expresión regular alterna de los elementos de $ requiredFruit. Emparejado con $ fruitIHave, devolverá todos los artículos que coincidan. Si $ fruitIhave podría tener duplicados de la misma fruta, es posible que deba ejecutar el resultado del partido a través de get-unique antes de realizar el recuento. Puede ser más lento que iterar sobre la lista para una sola comparación, pero una vez que haya construido la expresión regular, hará coincidencias repetitivas de manera muy eficiente.

0

De una forma u otra, tendrá que iterar a través de una o ambas matrices. Aquí hay un enfoque de una sola línea:

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

Un bucle foreach sería mejor porque se puede dejar de iterar tan pronto como se encuentre una fruta requiere que falta:

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

     break; 
    } 
} 
+1

@Anonymous Coward: Why the downvote? – BACON

11

Si tiene las matrices:

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

, usted puede obtener un resultado booleano con:

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

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

Usando el recuento de una matriz protege contra un único valor que no coincida con que se evalúa como Falso. Por ejemplo:

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

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

Con PowerShell v3, puede utilizar select -first 1 para detener la tubería cuando se encuentra la primera falta de coincidencia (en la versión 2 select -first 1 permite sólo un objeto a través, pero los elementos anteriores de la tubería seguir para procesar).

-not @($requiredFruit| where {$moreFruit -notcontains $_}| select -first 1).Count 
Cuestiones relacionadas