2009-10-08 88 views

回答

14

這樣做是使用一個Set作爲輔助數據結構的最有效的保序方式:

def unique[A](ls: List[A]) = { 
    def loop(set: Set[A], ls: List[A]): List[A] = ls match { 
    case hd :: tail if set contains hd => loop(set, tail) 
    case hd :: tail => hd :: loop(set + hd, tail) 
    case Nil => Nil 
    } 

    loop(Set(), ls) 
} 

我們可以使用隱式轉換將其包裝成一些更好的語法:

implicit def listToSyntax[A](ls: List[A]) = new { 
    def unique = unique(ls) 
} 

List(1, 1, 2, 3, 4, 5, 4).unique // => List(1, 2, 3, 4, 5) 
+9

現在過於複雜*。斯卡拉2.7沒有更好的東西。 – 2011-07-13 14:00:22

9

如果你指的是Rosetta Code: Create a Sequence of unique elements

val list = List(1,2,3,4,2,3,4,99) 
val l2 = list.removeDuplicates 
// l2: scala.List[scala.Int] = List(1,2,3,4,99) 

由於List是不可變的,你不會調用removeDuplicates

警告修改初始List:(!),如this tweet提到的,這種不保留訂單:

scala> val list = List(2,1,2,4,2,9,3) 
list: List[Int] = List(2, 1, 2, 4, 2, 9, 3) 

scala> val l2 = list.removeDuplicates 
l2: List[Int] = List(1, 4, 2, 9, 3) 

對於Seq,根據ticket 929,該方法應該在Scala2.8中可用。
在此期間,您需要定義一個特設的靜態方法爲one seen here

+0

如果我有Seq [String]而不是List? – 2009-10-08 15:46:59

+0

調用'toList',顯然是:)或者,如@Synesso提議的那樣,使用'foldLeft'。 – incarnate 2011-10-24 13:22:23

2

一個簡單的ad-hoc方法只是添加到列表中的設置,並使用從那裏:

val l = List(1,2,3,3,3,4,5,5,6,7,8,8,8,9,9) 
    val s = Set() ++ x 
    println(s) 

產地:

> Set(5, 1, 6, 9, 2, 7, 3, 8, 4) 

這適用於一個SEQ(或任何可迭代),但這並不是必需在2.8,其中removeDuplicates方法將可能是更具有可讀性。此外,不確定運行時性能與更深思熟慮的轉換。

另外,請注意丟失的順序。

10

推出自己的uniq的過濾器,以便保留:

scala> val l = List(1,2,3,3,4,6,5,6) 
l: List[Int] = List(1, 2, 3, 3, 4, 6, 5, 6) 

scala> l.foldLeft(Nil: List[Int]) {(acc, next) => if (acc contains next) acc else next :: acc }.reverse 
res0: List[Int] = List(1, 2, 3, 4, 6, 5) 
+3

我非常喜歡這個,因爲它允許複雜的過濾邏輯。謝謝! – incarnate 2011-10-24 13:20:32

178

在2.8,它是:

List(1,2,3,2,1).distinct // => List(1, 2, 3) 
+0

Imho,1和2不是列表中的唯一項目。只有3個。您從列表中創建唯一項目列表,這是不同的事情。 – 2012-05-11 20:02:33

+13

如果這就是你想要的(通常不是),請使用: List(1,2,3,2,1).groupBy(x => x).filter(_._ 2.lengthCompare(1)== 0).keySet – moveaway00 2013-07-03 15:56:47

6

恕我直言,這個問題所有的解釋都是假的:

如何在Scala中找到列表獨特的項目?

鑑於此列表:

val ili = List (1, 2, 3, 4, 4, 3, 1, 1, 4, 1) 

在列表中唯一的獨特產品2。其他項目不是唯一的。

ili.toSet.filter (i => ili.indexOf (i) == ili.lastIndexOf (i)) 

會找到它。

+3

大多數java/scala開發人員會將「給定列表中的唯一項目」的問題翻譯爲「給定列表中的所有不同值」而不是「在給定列表中單獨顯示的所有值」......這是你的每個答案如何解釋它,以及提問的人(誰批准了這樣的答案)。 2年後會出現什麼情況,並且在解析已經回答的問題時特別敏感? – mujimu 2012-07-02 20:04:44

+1

@mujimu:我不記得爲什麼2年後我偶然發現了這個問題。也許sombebody關閉了一個類似的問題,確切的重複並鏈接到這裏。在尋找其他人的解決方案之前,我經常嘗試爲自己回答這些問題作爲練習;他們是否有類似或更好的解決方案,或者是否合理發佈我的作品。所以我發現其他人回答了另一個問題。在瞭解其他人如何理解這個問題後,我仍然認爲這個術語是錯誤的。一個句子的含義不應該由多數人來判斷。 – 2012-07-03 10:13:05

2
list.filter { x => list.count(_ == x) == 1 } 
0

list。toSet將這樣做,因爲Set按定義只包含唯一元素

+0

5年前,在之前的回答中指出了這一點,你的觀點是什麼? – jwvh 2017-02-20 05:28:35