В Powershell, как я могу проверить, существуют ли все элементы из одного массива во втором массиве?
Итак, скажем, у меня есть этот массив:
$requiredFruit= @("apple","pear","nectarine","grape")
И мне присваивается второй массив под названием $fruitIHave
. Как я могу проверить, что $fruitIHave
имеет все в $requiredFruit
. Не имеет значения, есть ли больше элементов в $fruitIHave
, пока все в $requiredFruit
есть.
Я знаю, что могу просто перебирать список, но это кажется неэффективным, есть ли встроенный метод для этого?
Ответы
Ответ 1
Попробуйте Compare-Object:
$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
Ответ 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;
Цикл A foreach
был бы лучше, потому что вы можете остановить итерацию, как только найдете нужный плод:
$hasAllRequiredFruit = $true;
foreach ($f in $requiredFruit)
{
if ($fruitIHave -notcontains $f)
{
$hasAllRequiredFruit = $false;
break;
}
}