2012-05-12 98 views
0

考虑该名单的情况下,类的实例对象组成:寻找最佳的解决方案

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)元素。

我想:

  • 在性能
  • 最短的解决方案
+0

所以等于元素只能出现一次?该列表是按字母顺序排序的?你为什么不使用Set? –

+0

列表不必排序。正如我所说:如果发现两个元素Opt(A)并且只是A,它们就会被A替代。我希望我已经清楚了。 – PrimosK

+0

“Opt”是什么意思?你的意思是选择? – ziggystar

回答

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

不是最有效的解决方案的平均最优化的解决方案,但肯定是一个简单的问题。

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

如果你不关心顺序则效率导致你使用一组:

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 
+0

你的解决方案不适用于像List(Some(1),1)这样的列表。 – drexin

+0

@drexin它产生'List(1)',如果我正确地阅读这个问题是正确的答案...? –

+0

哦,你说得对,我在repl中使用了':paste',它将任务返回给'xs'。但是你确定为列表中的每个值创建'Option'的实例,然后进行查找并始终创建新的不可变实例'Set'比使用'List'的查找'filter'更有效。我认为'xs.toSet'上的'filter'会更好。 – drexin