Finding an item that matches predicate in Scala

旧时模样 提交于 2019-12-03 06:13:51

问题


I'm trying to search a scala collection for an item in a list that matches some predicate. I don't necessarily need the return value, just testing if the list contains it.

In Java, I might do something like:

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

In Groovy, I can do something like:

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

What's the idiomatic way to do this in Scala? I could of course convert the Java loop style to Scala, but I feel like there's a more functional way to do this.


回答1:


Use filter:

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

But if all you need is to check use exists:

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



回答2:


Testing if value matching predicate exists

If you're just interested in testing if a value exists, you can do it with.... 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

Other methods (some based on comments):

Counting matching elements

Count elements that satisfy predicate (and check if count > 0)

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

Returning first matching element

Find the first element that satisfies predicate (as suggested by Tomer Gabel and Luigi Plinge this should be more efficient because it returns as soon as it finds one element that satisfies the predicate, rather than traversing the whole List anyway)

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

Testing if exact value exists

For the simple case where we're actually only checking if one specific element is in the list

scala> l contains 2
res7: Boolean = true



回答3:


The scala way would be to use exists:

collection.exists(item => condition1(item) && condition2(item))

And since java 8 you can use anyMatch:

collection.stream().anyMatch(item -> condition1(item) && condition2(item));

which is much better than a plain for or foreach.




回答4:


Filter and exists keywords to get the matching values from Lists

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

Given code helps to get the matching values from 2 different lists



来源:https://stackoverflow.com/questions/9556579/finding-an-item-that-matches-predicate-in-scala

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!