1

distinctLastBy次の方法の優れたパフォーマンスを備えたソリューションを探しています。

import scala.language.higherKinds
implicit final class SeqPimp[A, S[A] <: Seq[A]](val s: S[A]) extends AnyVal {
  import scala.collection.generic.CanBuildFrom
  import scala.collection.mutable.Builder
  private final def build[B](build: Builder[B, S[B]] => Unit)(implicit cbf: CanBuildFrom[S[A], B, S[B]]): S[B] = {
    val b = cbf()
    build(b)
    b.result
  }
  final def distinctBy[B](f: A => B)(implicit cbf: CanBuildFrom[S[A], A, S[A]]): S[A] = {
    build[A] { builder =>
      val seen = scala.collection.mutable.Set[B]()
      for (a <- s; b = f(a); if !(seen contains b)) {
        seen += b
        builder += a
      }
    }
  }
  final def distinctLastBy[B](f: A => B)(implicit cbf: CanBuildFrom[S[A], A, S[A]]): S[A] = {
    // instead of keeping the first occurence of an element the last one will be kept
    build[A] { builder => builder ++= s.view.reverse.distinctBy(f).reverse }
  }
}

例:

case class Num(integralDigits: Int, fractionalDigits: Int)
val nums = Num(2, 11) :: Num(1, 23) :: Num(1, 45) :: Num(3, 11) :: Num(2, 22) :: Nil
nums distinctLastBy (_.integralDigits) // List(Num(1,45), Num(3,11), Num(2,22))

by元のリストで(-引数の) 最初に出現した順に並べ替えられた結果要素があると便利です。

List(Num(2,22), Num(1,45), Num(3,11))

何か案は?

4

2 に答える 2

1

ビルダーを使用して実装を維持したい場合は、@ James_pic の回答しか確認できません。SortedMap最後にキーをソートしたい場合は、 a の使用を検討してください。

別の、よりコード軽量な可能性は次のとおりです。

nums.groupBy(_.integralDigits).map(_._2.last)
于 2013-05-17T14:48:01.513 に答える