Инструкция elseif функции Powershell не работает

У меня есть функция PowerShell, которая не работает должным образом. Предполагается, что количество вариантов, заданных ему в $ prm, должно быть ограничено максимум 5. Более пяти он должен предупреждать пользователя. Если в строке передается 0, то по умолчанию принимается значение null.

Может кто-нибудь посоветует, что мне нужно сделать, чтобы это исправить:

Function GetListValues($prm, $charCount){ 

$buildStr = "Call db.Fruit(" 

#no selection
if ($charCount -eq 0 ){ 
    $buildStr = $buildStr + "NULL,NULL,NULL,NULL,NULL);"
    write $buildStr
}elseif ($charCount -ge 1 -and $charCount -le 4 ){

#selections made with then 5 parameter range

$arr = $prm.split(",");
if ($arr[0]) { $buildStr = $buildStr  + $arr[0] + "," } else { $buildStr = $buildStr + "Null," }
if ($arr[1]) { $buildStr  = $buildStr + $arr[1] + "," } else { $buildStr = $buildStr + "Null," }
if ($arr[2]) { $buildStr  = $buildStr + $arr[2] + "," } else { $buildStr = $buildStr + "Null," }
if ($arr[3]) { $buildStr  = $buildStr + $arr[3] + "," } else { $buildStr = $buildStr + "Null," }
if ($arr[4]) { $buildStr  = $buildStr + $arr[4] + ");" } else {$buildStr =  $buildStr + "Null);" }

write $buildStr


}else{
# too many selections

[System.Windows.MessageBox]::Show('Too many selections! A maximum of 5 only!')


}


}
$prm = "'Apple','Orange','Pear','Banana','Grapes'"
$charCount = ($prm.ToCharArray() | Where-Object {$_ -eq ','} | Measure-Object).Count
GetListValues $prm, $charCount
Что такое компоненты React? Введение в компоненты | Типы компонентов
Что такое компоненты React? Введение в компоненты | Типы компонентов
Компонент - это независимый, многократно используемый фрагмент кода, который делит пользовательский интерфейс на более мелкие части. Например, если мы...
2
0
187
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Полезный ответ DeanOC указывает на вашу непосредственную проблему с синтаксисом передачи аргументов.

Кроме того, как он предлагает, вам не нужно определять количество элементов вне функции - проще и надежнее позволить самой функции обрабатывать это. Вот идиоматическая переформулировка вашей функции в стиле PowerShell, которая делает именно это:

function GetListValues {
  param(
    [ValidateCount(0,5)] # Allow between 0 and 5 values.
    [string[]] $Columns
  )
  # Create a 5-element array filled with the input column names
  # and 'Null' for any remaining elements.
  $allColumns = New-Object string[] 5
  for ($i = 0; $i -lt $allColumns.Count; ++$i) {
    $allColumns[$i] = if ($i -lt $Columns.Count) { $Columns[$i] } else { 'Null' }
  }
  # Use string expansion (interpolation) to construct the output string.
  "Call db.Fruit($($allColumns -join ','))"
}

Определение параметра как [string[]] позволяет вам (а) передавать имена столбцов по отдельности и (б) легко дает вам доступ к их количеству и позволяет ограничивать допустимый диапазон имен столбцов с помощью атрибута ValidateCount.

Поэтому вы можете вызвать указанную выше функцию следующим образом:

# Pass 5 column names.
# Note that with the simple names at hand you needn't even quote them.
PS> GetListValues Apple, Orange, Pear, Banana, Grapes

Call db.Fruit(Apple,Orange,Pear,Banana,Grapes)

# Pass no column names at all.
PS> GetListValues

Call db.Fruit(Null,Null,Null,Null,Null)

# Pass too many names -> ValidateCount triggers an error.
PS> GetListValues Apple, Orange, Pear, Banana, Grapes, TooMuch

GetListValues : Cannot validate argument on parameter 'Columns'. 
The parameter requires at least 0 value(s) and no more than 5 value(s)
- 6 value(s) were provided.

Вариант решения (запрошенный позже OP), который:

  • позволяет пройти макс. количество столбцов как параметр

  • передает имена столбцов как одну строку со встроенными кавычками (например, "'Apple', 'Orange', 'Pear', 'Banana', 'Grapes'").

function GetListValues {
  param(
    [string] $ColumnList,
    [int]    $MaxColumnCount
  )

  # Split something like "'Apple', 'Orange', 'Pear', 'Banana', 'Grapes'"
  # into an array of tokens.
  $Columns = $ColumnList -split "[, ']" -ne ''
  if ($Columns.Count -gt $MaxColumnCount) { Throw "Too many columns passed." }

  # Create an N-element array filled with the input column names
  # and 'Null' for any remaining elements.
  $allColumns = New-Object string[] $MaxColumnCount
  for ($i = 0; $i -lt $allColumns.Count; ++$i) {
    $allColumns[$i] = if ($i -lt $Columns.Count) { $Columns[$i] } else { 'Null' }
  }
  # Use string expansion (interpolation) to construct the output string.
  "Call db.Fruit($($allColumns -join ','))"
}

Примеры звонков:

PS> GetListValues "'Apple', 'Orange', 'Pear', 'Banana', 'Grapes'" 5

Call db.Fruit(Apple,Orange,Pear,Banana,Grapes)

PS> GetListValues "" 3

Call db.Fruit(Null,Null,Null)
Ответ принят как подходящий

Ваша проблема связана с тестовым кодом, а не с функцией. В PowerShell для разделения параметров используются только пробелы, а не запятые.

Итак, если вы измените свой тест на

GetListValues $prm $charCount

Тогда код работает.

Вы можете проигнорировать мой предыдущий комментарий, поскольку я предполагал, что ваше значение $ charCount было установлено равным количеству элементов. Но при ближайшем рассмотрении я вижу, что вы просто подсчитываете количество запятых, и поэтому количество элементов будет # запятые + 1 (если у вас> 1 элементов)

Кстати, $ charCount несколько избыточен, поскольку функция может решить это сама и сделает функцию более устойчивой, поскольку это устранит возможность передачи вызывающим кодом несогласованных значений.

Спасибо Дину за советы. Я не особо разбираюсь в Powershell. Я больше сторонник javascript и кода в этом смысле. Да, вы правы насчет функции, обрабатывающей $ charCount. Я просто переместил его, чтобы попытаться упростить и изолировать свою ошибку.

Tired_Eyes 24.05.2018 02:03

Другие вопросы по теме