2014-09-17 2 views
0

Есть ли более эффективный способ поиска нескольких массивов для определенного значения? Это не так уж плохо, но если бы у меня было 50 массивов, это вышло бы из-под контроля. Я тоже думал о том, чтобы делать переключатель, но я надеялся на какой-то метод итерации массива.Powershell поиск нескольких массивов для переменных

$A = "A","B","C" 
$B = "X","Y","Z" 
$C = "B" 

If ($A -contains $C) {$D = "Contained in Array A"} 
ElseIF ($B -contains $C) {$D = "Contained in Array B"} 

ответ

2

Вот альтернатива, чтобы сделать это немного более динамично.

$A = "A","B","C" 
$B = "X","Y","Z" 
$C = "B" 

$ArrayList = (get-variable) | ? {$_.value -is [array]} 
Foreach ($Array in $ArrayList) 
{ 
    if ($array.value -contains $c) 
    {Write-Output "The array `$$($array.name) contains $C"} 
} 
+0

Удивительно, я собирался опубликовать что-то вроде этого, но не думал о сравнении с типом '[array]' и не мог обернуть мою голову альтернативным методом для этого. – TheMadTechnician

+0

Я также пытался найти способ использовать 'get-variable', чтобы знать, что кто-то его получил. – Matt

+0

Какую функцию выполняют скобки вокруг «массива»? -> [array] – Matt

0

я могу думать о других способах, но просто один может быть это

$A = "A","B","C" 
$B = "X","Y","Z" 
$C = "X" 

$AllArrays = @{'A'=$A;'B'=$B} 
$AllArrays.GetEnumerator() | ForEach-Object{ 
    If($_.Value -contains $C){ 
     Write-Host "Found In $($_.Name)" 
    } 
} 

Вы можете создать хэш-таблицу всех массивов, а затем цикл через него. Каждый .Value хэш-таблицы содержит один из массивов. Вы по-прежнему используете -contains и отчитываете имя массива из исходной хеш-таблицы. Мы используем метод GetEnumerator, который эффективно отправляет каждую запись в хэш-таблицу по конвейеру как отдельный объект. FYI если ваши массивы не статически можно построить хэш-таблицу с чем-то вроде $AllArrays.Add('D',$D)

Found In B 

The B приходит из 'B'=$B в хэш-таблице. Все зависит от того, как вы объявляете свои массивы. Могут быть более чистые способы в зависимости от того, как заполняются ваши массивы.

Alternative

Вместо Hashtable вы можете использовать PSCustomObject. Примечание Этот код был разработан в PowerShell 3.0, но небольшие изменения заставят его работать в более ранних версиях. В этом фрагменте я сократил объявления массива для краткости.

$allArrays = [PsCustomObject]@{ 
    'A'=$A 
    'B'=$B 
} 

$allArrays.psobject.Properties | ForEach-Object{ 
    If($_.Value -contains $C){ 
     Write-Host "Found In $($_.Name)" 
    } 
} 
+0

Я думал о публикации этого, но на самом деле это заканчивается тем, что он не менее эффективен, чем создание переключателя, чтобы сделать это, и он искал что-то более общее или более короткое. Ваш ответ работает, я просто не думаю, что это было в духе вопроса. – TheMadTechnician

+0

Для 50 некоторых массивов это может быть утомительным. Я бы подумал, что одно задание, цикл и оператор if будет легче читать, чем довольно большой оператор switch. @TheMadTechnician Я пытался намекнуть, что это плохое решение только потому, что я сомневался, что OP будет иметь скрипт с 50 некоторыми статическими определенными массивами. Если бы это было так, то ответ Ноаса был лучшим. Но я думаю, что его массивы могут исходить из другого источника, и в этом случае этот цикл будет учитывать любое количество массивов. – Matt

0

Чтобы ответить на этот вопрос, как спросил:

$A = "A","B","C" 
$B = "X","Y","Z" 
$C = "B" 

$D= @() 

'A','B' | 
foreach { 
if ((Get-Variable $_).value -eq $C) 
{ $D += "Contained in array $_"} 
} 

$D 

Contained in array A 

Хотя я подозреваю, что может быть лучше решения этой проблемы, но не могу рассуждать, не зная об этом.

Смежные вопросы