web-dev-qa-db-ja.com

Scalaの述語に一致するアイテムを見つける

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に変換することもできますが、これにはもっと機能的な方法があると感じています。

49
Jeff Storey

フィルターを使用:

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
55
om-nom-nom

値一致述語が存在するかどうかのテスト

値が存在するかどうかをテストするだけの場合は、次の方法で実行できます。..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

その他の方法(コメントに基づくもの):

一致する要素のカウント

述語を満たす要素を数えます(そしてcount> 0かどうかを確認します)

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

最初に一致した要素を返す

述語を満たす最初の要素を見つけます(Tomer GabelとLuigi Plingeが示唆するように、リスト全体を横断するのではなく、述語を満たす1つの要素を見つけるとすぐに戻るため、これはより効率的です)

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
53
Paolo Falabella

scala方法はexistsを使用することです:

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

また、Java 8なので、anyMatchを使用できます。

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

forまたはforeachのプレーンよりもはるかに優れています。

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つの異なるリストから一致する値を取得するのに役立ちます

0
Yuva Yuvi