2017-02-14 3 views
-5

У меня есть массив объектов, который мне нужен для применения фильтра.Использование тернарного оператора в программе Scala

val filteredList = list.filter{ l => (pid == "") ? true : l.ProviderId.toUpperCase().contains(pid.toUpperCase()))} 

Этот код не выполняется компилятором Scala. Я получаю ошибку, как 1) значение? не является членом boolean 2) Тип toUpperCase не является членом строки.

Может кто-нибудь, пожалуйста, помогите мне, как написать этот тернарный оператор внутри функции фильтра в scala.

Я согласен с тем, что я могу написать пользовательскую функцию для обработки этого, как указано @Ternary Operators in Scala Однако меня интересует, почему для этого утверждения существует ошибка компиляции. Потому что это действительный оператор в Java.

+0

Что такое 'pid'? вы имеете в виду 'l ==" "'? – mrsrinivas

+2

Не прямой ответ на ваш вопрос, но 'if (pid ==" ") true' является избыточным. Вы можете написать это выражение как 'pid ==" "|| l.ProviderId.toUpperCase(). содержит (pid.toUpperCase()) ' –

+1

Возможный дубликат [Тернарные операторы в Scala] (http://stackoverflow.com/questions/40643839/ternary-operators-in-scala) –

ответ

1

Основная проблема заключается в том, что Scala не поддерживает описанный вами тернарный оператор. Это поддерживается Java, но в Scala нет необходимости.

В Java основное различие между ifзаявлением и тройным оператором, что последний является выражением, а это означает, что она оценивается в результат, в то время как if (как я ранее предложил) заявление, которое опирается на стороне -эффекты в пределах его возможностей, чтобы все произошло.

В Scala if уже есть выражение, поэтому нет необходимости в тройном операторе.

Ваш код будет структурирована следующим образом:

val filteredList = list.filter { l => if (pid == "") true else l.ProviderId.toUpperCase().contains(pid.toUpperCase()) } 

Как было предложено в комментарии можно дополнительно улучшить читаемость, не полагаясь на if с, чтобы выразить простые логические условия.

val filteredList = list.filter { l => pid == "" || l.ProviderId.toUpperCase().contains(pid.toUpperCase())) } 

Кроме того, в вашем случае, pid кажется, внешними по отношению к самому списку, так что, может быть, потянув его из filter (который имеет О (п) сложности на List) может сэкономить вам несколько циклов:

val filteredList = if (pid.isEmpty) list else list.filter(_.ProviderId.toUpperCase().contains(pid.toUpperCase())) 

Это также выглядит, как вы пытаетесь сделать случай-insensive проверку равенства на две строки, в этом случае вы можете быть заинтересованы в использовании Pattern и не преобразования pid в верхний регистр при каждом цикле:

val pidPattern = Pattern.compile(Pattern.quote(pid), Pattern.CASE_INSENSITIVE) 

val filteredList = if (pid.isEmpty) list else list.filter(l => pidPattern.matcher(l.ProviderId).find) 
+0

Поблагодарите stefanobaghino за то, что вы указали лучшие практики и способ правильно их кодировать. –

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