Поиск элемента, который соответствует предикату в Scala - PullRequest
46 голосов
/ 04 марта 2012

Я пытаюсь найти в коллекции 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 ]

53 голосов
/ 04 марта 2012

Тестирование, если существует предикат соответствия значения

Если вы просто заинтересованы в тестировании, существует ли значение, вы можете сделать это с помощью .... 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

Возврат первого соответствующего элемента

Найдите первый элемент, который удовлетворяет предикату (как предложено Томером Габелем и Луиджи Плинге, это должно быть более эффективным, потому что он возвращается, как только находит один элемент, который удовлетворяет предикату, а не обходит весь список в любом случае)

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 голосов
/ 04 марта 2012

Используйте фильтр:

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
0 голосов
/ 15 мая 2019

Фильтр и существующие ключевые слова для получения соответствующих значений из списков

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 голосов
/ 06 сентября 2018

В Scala можно использовать exists:

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

И, начиная с Java 8, вы можете использовать anyMatch:

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

, что намного лучше, чем обычнаядля или foreach.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...