лучшая идиома для поиска и возврата - PullRequest
6 голосов
/ 18 марта 2010

Это то, с чем я часто сталкиваюсь, но я не знаю элегантного способа сделать это. У меня есть коллекция объектов Foo. У Foo есть метод bar (), который может возвращать null или объект Bar. Я хочу отсканировать коллекцию, вызывая метод bar () каждого объекта и останавливаясь на первом, возвращая фактическую ссылку и возвращая эту ссылку из сканирования.

Очевидно:

foos.find (_. Bar! = Null) .bar

делает трюк, но дважды вызывает #bar.

Ответы [ 2 ]

8 голосов
/ 18 марта 2010

Работа над потоком [T], возвращаемым Seq.projection - хороший трюк

foos.projection map (_.bar) find (_.size > 0)

Это отобразит значения, необходимые для выполнения поиска.

В Scala 2.8 это:

foos.view map (_.bar) find (_.size > 0)
7 голосов
/ 18 марта 2010

Вы можете сделать это с любым Iterable, используя iterator (который оценивается лениво - это называется elements в 2.7). Попробуйте это:

case class Foo(i: Int) {
  def bar = {
    println("Calling bar from Foo("+i+")")
    (if ((i%4)==0) "bar says "+i else null)
  }
}
val foos = List(Foo(1),Foo(2),Foo(3),Foo(4),Foo(5),Foo(6))
foos.iterator.map(_.bar).find(_!=null)
...