1

coll: C[A]コレクションと functionが与えられた場合、 Scala でコレクション全体を評価せずに定義されf: A => Option[B]た最初の項目を取得する慣用的な方法は何ですか?collf

これが私の意図した署名です:

def findFirstDefined[A, B](coll: Traversable[A])(f: A => Option[B]): Option[B]

coll.flatMap(f).headOptionコレクション全体を評価するような素朴なアプローチです。できるかもしれませんが、標準ライブラリ、関数型プログラミングの文献、coll.view.flatMap(f).headOptionまたはcoll.collectFirst(Function.unlift(f))scalaz/cats のいずれかに、これを可能にするものが他にありますか?

4

3 に答える 3

2

coll.collectFirst(Function.unlift(f))標準的なものを使用したい場合、IMOは良い解決策のように見えます。しかし、再帰を使用して実装するのは非常に簡単です。

@annotation.tailrec
def findFirstDefined[A, B](coll: Traversable[A])(f: A => Option[B]): Option[B] =
  if (coll.isEmpty) None
  else {
    val r = f(coll.head)
    if (r.isEmpty) findFirstDefined(coll.tail)(f)
    else r
  }
于 2016-10-02T16:56:45.337 に答える
0

を使用するのはfind(p: A => Boolean)どうですか?

def findFirstDefined[A, B](coll: Traversable[A])(f: A => Option[B]): Option[B] =
    coll.find(f(_).isDefined).flatMap(f(_))

これには を 2 回呼び出す必要がありますが、定義されたオプションを返す最初の要素が見つかるまでf.apply()しか呼び出されません。apply()

編集:それについて考えてみてください(しかし、ビクターは私を打ち負かしました)、collectFirst()よりエレガントなオプションもあります:

coll.collectFirst(Function.unlift(f))
于 2016-10-02T16:41:00.500 に答える
0

質問で述べたように、これはまともな解決策のようです:

def findFirstDefined[A, B](coll: Traversable[A])(f: A => Option[B]): Option[B] = 
  coll.collectFirst(Function.unlift(f))
于 2016-10-07T14:34:12.270 に答える