查找与Scala中的谓词匹配的项

Jef*_*rey 51 collections scala idiomatic

我正在尝试在scala集合中搜索与某个谓词匹配的列表中的项目.我不一定需要返回值,只测试列表是否包含它.

在Java中,我可能会这样做:

for ( Object item : collection ) {
    if ( condition1(item) && condition2(item) ) {
       return true;
    }
}
return false;
Run Code Online (Sandbox Code Playgroud)

在Groovy中,我可以做类似的事情:

return collection.find { condition1(it) && condition2(it) } != null
Run Code Online (Sandbox Code Playgroud)

在Scala中执行此操作的惯用方法是什么?我当然可以将Java循环样式转换为Scala,但我觉得有一种更实用的方法可以做到这一点.

om-*_*nom 55

使用过滤器:

scala> val collection = List(1,2,3,4,5)
collection: List[Int] = List(1, 2, 3, 4, 5)

// take only that values that both are even and greater than 3 
scala> collection.filter(x => (x % 2 == 0) && (x > 3))
res1: List[Int] = List(4)

// you can return this in order to check that there such values
scala> res1.isEmpty
res2: Boolean = false

// now query for elements that definitely not in collection
scala> collection.filter(x => (x % 2 == 0) && (x > 5))
res3: List[Int] = List()

scala> res3.isEmpty
res4: Boolean = true
Run Code Online (Sandbox Code Playgroud)

但如果您只需要检查使用exists:

scala> collection.exists( x => x % 2 == 0 )
res6: Boolean = true
Run Code Online (Sandbox Code Playgroud)

  • 更简单的`集合存在{x => condition1(x)&& condition2(x)}` (7认同)

Pao*_*lla 54

测试值匹配谓词是否存在

如果您只是想测试一个值是否存在,那么您可以使用.... exists

scala> val l=(1 to 4) toList
l: List[Int] = List(1, 2, 3, 4)

scala> l exists (_>5)
res1: Boolean = false

scala> l exists (_<2)
res2: Boolean = true

scala> l exists (a => a<2 || a>5)
res3: Boolean = true
Run Code Online (Sandbox Code Playgroud)

其他方法(一些基于评论):

计算匹配元素

计算满足谓词的元素(并检查count是否> 0)

scala> (l count (_ < 3)) > 0
res4: Boolean = true
Run Code Online (Sandbox Code Playgroud)

返回第一个匹配元素

找到满足谓词的第一个元素(正如Tomer Gabel和Luigi Plinge所建议的那样,这应该更有效,因为它一找到一个满足谓词的元素就会返回,而不是反过来遍历整个List)

scala> l find (_ < 3)
res5: Option[Int] = Some(1) 

// also see if we found some element by
// checking if the returned Option has a value in it
scala> l.find(_ < 3) isDefined
res6: Boolean = true
Run Code Online (Sandbox Code Playgroud)

测试是否存在确切值

对于我们实际上只检查列表中是否有一个特定元素的简单情况

scala> l contains 2
res7: Boolean = true
Run Code Online (Sandbox Code Playgroud)

  • 它是`find`,而不是`findFirst`,但是这比过滤整个列表更有效 (3认同)