我有一个需要应用过滤器的对象数组。
val filteredList = list.filter{ l => (pid == "") ? true : l.ProviderId.toUpperCase().contains(pid.toUpperCase()))}
Scala编译器无法编译此代码。我得到的错误就像 1)价值?不是布尔值的成员 2)类型toUpperCase不是字符串的成员。
任何人都可以帮助我如何在scala中的过滤器函数内编写这个三元运算符。
我同意我可以编写一个自定义函数来处理这个问题@ Ternary Operators in Scala 但是,我感兴趣的是为什么这个语句有编译错误。 因为,这是Java中的有效语句。
答案 0 :(得分:1)
主要问题是Scala不支持您描述的三元运算符。这支持Java,但在Scala中不需要它。
在Java中,if
语句与三元运算符之间的主要区别在于后者是一个表达式,意味着它被评估为结果,而{{{ 1}}(正如我之前所建议的那样)是一种声明,它依赖于其范围内的副作用来实现目标。
在Scala中if
已经是一个表达式,因此不需要三元运算符。
您的代码结构如下:
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
(具有 O(n)复杂度的filter
中拉出来在List
)可以节省一些周期:
val filteredList = if (pid.isEmpty) list else list.filter(_.ProviderId.toUpperCase().contains(pid.toUpperCase()))
看起来你也试图对这两个字符串进行大小写密集检查,在这种情况下,你可能有兴趣使用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)