Почему оператор сравнения не работает после перечисления?

#powershell #comparison

#powershell #сравнение

Вопрос:

У меня есть довольно простой пример использования ниже, где мне нужно найти, существует ли определенный элемент массива. Почему условный оператор в этом случае не работает?

 @("a", "b").Where{$_ -eq "a"} -eq $true
  

Ответ №1:

.Where() Метод array действует как фильтр (как и его аналог в командлете Where-Object ), поэтому он возвращает подмассив[1] совпадающих элементов, а не логическое значение.

Для простой проверки на равенство [2] вместо этого можно использовать логический -contains оператор:

 ('a', 'b') -contains 'a' # -> $true
  

Если вам нужен более сложный тест на основе скриптовых блоков с помощью .Where() :

 ('a', 'b').Where({ $_ -in 'a', 'z' }, 'First').Count -ne 0
  

Обратите внимание на 'First' аргумент the , который, в качестве важной оптимизации, .Where() возвращает возврат после того, как найдено первое совпадение.

Поскольку результат всегда заключен в массив [1], проверки .Count свойства достаточно, чтобы определить, было ли найдено совпадение.


[1] Технически возвращается коллекция типов [System.Collections.ObjectModel.Collection[psobject]] .

[2] Обратите внимание, что PowerShell по умолчанию не учитывает регистр, но он предлагает c версии своих операторов сравнения с префиксами для операций, учитывающих регистр; например, -ccontains , или для эквивалентных операндов -обратный -in оператор, -cin .

Комментарии:

1. Есть также "a" -in @("a", "b") , @("a", "b").Contains("a") и @("a", "b").IndexOf("a") -ge 0 и другие способы, но мне лично больше всего нравится 2 из этого ответа.

2. Хорошее дополнение, @marsze, спасибо; обратите внимание, что .Contains() и .IndexOf() чувствительны к регистру .