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

时间:2012-03-04 16:23:42

标签: scala collections idiomatic

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

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

for ( Object item : collection ) {
    if ( condition1(item) && condition2(item) ) {
       return true;
    }
}
return false;

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

return collection.find { condition1(it) && condition2(it) } != null

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

4 个答案:

答案 0 :(得分:53)

测试值匹配谓词是否存在

如果您只是想测试某个值是否存在,那么您可以使用.... 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

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

计算匹配元素

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

scala> (l count (_ < 3)) > 0
res4: Boolean = true

返回第一个匹配元素

找到满足谓词的第一个元素(正如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

测试是否存在确切值

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

scala> l contains 2
res7: Boolean = true

答案 1 :(得分:51)

使用过滤器:

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

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

scala> collection.exists( x => x % 2 == 0 )
res6: Boolean = true

答案 2 :(得分:0)

scala方法是使用SELECT v.gid, v2.gid,st_distance(v.the_geom, v2.the_geom) FROM geonames v, lateral(select * from geonames v2 where v2.id<>v.id ORDER BY v.the_geom <-> v2.the_geom LIMIT 10) v2 where v.gid in (...) - or other filtering condition

exists

从Java 8开始,您可以使用collection.exists(item => condition1(item) && condition2(item))

anyMatch

这比普通的foreach更好。

答案 3 :(得分:0)

过滤并存在关键字以从列表中获取匹配的值

val values = List(1,2,3,4,5,6,7,8,9,10,....,1000) //List -1
val factors= List(5,7) // List -2

//To get the factors of List-2 from List-1
values .filter(a => factors.exists(b => a%b == 0)) //Apply different logic for our convenience

给出的代码有助于从2个不同的列表中获取匹配的值