Как найти соответствующий элемент в списке и отобразить его как метод Scala API?
Есть ли способ сделать следующее без использования обоих методов: find и map?
val l = 0 to 3
l.find(_ * 33 % 2 == 0).map(_ * 33) // returns Some(66)
Ответ 1
Как насчет использования collect?
// Returns List(66)
List(1, 2, 3) collect { case i if (i * 33 % 2 == 0) => i * 33 }
Однако это вернет все совпадения, а не только первый.
Лучший ответ был бы, основываясь на Scala 2.9:
// Returns Some(66)
List(1, 2, 3) collectFirst { case i if (i * 33 % 2 == 0) => i * 33 }
Решение, предложенное в комментариях для добавления head, чтобы получить версию Scala 2.8, не очень эффективно, я боюсь. Возможно, в этом случае я буду придерживаться собственного кода. В любом случае, чтобы убедиться, что он возвращает параметр, вы не должны называть head, но headOption.
// Returns Some(66)
List(1, 2, 3) collect { case i if (i * 33 % 2 == 0) => i * 33 } headOption
Ответ 2
Если вы не хотите выполнять свою операцию map() несколько раз (например, если это дорогостоящий поиск БД), вы можете сделать это:
l.view.map(_ * 33).find(_ % 2 == 0)
view делает коллекцию ленивой, поэтому число операций map() минимизировано.
Ответ 3
Эй, смотри, это мой маленький приятель findMap снова!
/**
* Finds the first element in the list that satisfies the partial function, then
* maps it through the function.
*/
def findMap[A,B](in: Traversable[A])(f: PartialFunction[A,B]): Option[B] = {
in.find(f.isDefinedAt(_)).map(f(_))
}
Обратите внимание, что, в отличие от принятого ответа, но, как и метод collectFirst, упомянутый в одном из своих комментариев, этот парень останавливается, как только находит соответствующий элемент.
Ответ 4
Это может сделать это, но было бы проще, если бы вы рассказали, чего вы действительно пытаетесь достичь: