2

多くの値が等しいかどうかを確認し、場合によっては共通の値を抽出する必要があることがよくあります。つまり、次のように機能する関数が必要です。

extract(List()) // None
extract(List(1,2,3)) // None
extract(List(2,2,2)) // Some(2)

seqsに追加tailOptionする pimp があると仮定すると (1 つ書くのは簡単で、scalaz に 1 つある)、1 つの実装は次のようになります。

def extract[A](l: Seq[A]): Option[A] = {

  def combine(s: A)(r: Seq[A]): Option[A] =
    r.foldLeft(Some(s): Option[A]) { (acc, n) => acc flatMap { v =>
      if (v == n) Some(v) else None
    } }

  for {
    h <- l.headOption
    t <- l.tailOption
    res <- combine(h)(t)
  } yield res
}

そのようなもの (おそらくもっと一般的なもの) は既に Scalaz にあるのでしょうか、それとももっと簡単に書く方法はありますか?

4

4 に答える 4

3

これは非常に複雑な書き方のようです

def extract[A](l:Seq[A]):Option[A] = l.headOption.flatMap(h =>
  if (l.tail.forall(h==)) Some(h) else None)

tailOption引数として渡される無名関数は が空でないflatMap場合にのみ実行されるため、は必要ありません。l

于 2012-09-26T13:26:47.213 に答える
2

これは流暢な解決策です

yourSeq.groupBy(x => x) match {case m if m.size==1 => m.head._1; case _ => None}
于 2012-09-26T14:41:49.833 に答える
2

重複を削除するtoSetだけで十分な場合:

def equalValue[A](xs: Seq[A]): Option[A] = {
  val set = xs.toSet
  if (set.size == 1) Some(set.head) else None
}

scala> equalValue(List())
res8: Option[Nothing] = None

scala> equalValue(List(1,2,3))
res9: Option[Int] = None

scala> equalValue(List(2,2,2))
res10: Option[Int] = Some(2)
于 2012-09-26T13:45:40.323 に答える