2012-05-12 104 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