寻找最佳解决方案

时间:2012-05-12 09:24:41

标签: performance scala optimization review

考虑这个由对象组成的列表,这些对象是案例类的实例:

A, B, Opt(A),C, Opt(D), F, Opt(C), G, Opt(H)

我想对此列表进行规范化以获得此结果:

A, B, C, Opt(D), F, G, Opt(H)

如您所见,如果有AOpt(A)元素,我只用A或其他方式替换它们,我必须删除OPT(A)元素。

我想:

  • 性能方面的最佳解决方案
  • 最短的解决方案

3 个答案:

答案 0 :(得分:2)

不是最有效的解决方案,但肯定是一个简单的解决方案。

scala> case class Opt[A](a: A)
defined class Opt

scala> val xs = List(1, 2, Opt(1), 3, Opt(4), 6, Opt(3), 7, Opt(8))
xs: List[Any] = List(1, 2, Opt(1), 3, Opt(4), 6, Opt(3), 7, Opt(8))

scala> xs flatMap {
     |   case o @ Opt(x) => if(xs contains x) None else Some(o)
     |   case x => Some(x)
     | }
res5: List[Any] = List(1, 2, 3, Opt(4), 6, 7, Opt(8))

答案 1 :(得分:2)

这可能更简洁,因为过滤就是你想要的; - ):

scala> List(1,2,3,Some(4),5,Some(5))
res0: List[Any] = List(1, 2, 3, Some(4), 5, Some(5))

scala> res0.filter {
     | case Some(x) => !res0.contains(x)
     | case _ => true
     | }
res1: List[Any] = List(1, 2, 3, Some(4), 5)

编辑:对于大型馆藏,最好使用toSet或直接使用Set

答案 2 :(得分:1)

如果您不关心订单,那么效率会导致您使用Set:

xs.foldLeft(Set.empty[Any])({ case (set, x) => x match {
  case Some(y) => if (set contains y) set else set + x
  case y => if (set contains Some(y)) set - Some(y) + y else set + y
}}).toList

可替换地:

val (opts, ints) = xs.toSet.partition(_.isInstanceOf[Option[_]])
opts -- (ints map (Option(_))) ++ ints toList