在Scala中,如何从列表中删除重复项?


94

假设我有

val dirty = List("a", "b", "a", "c")

是否有返回“ a”,“ b”,“ c”的列表操作

Answers:


175

看看ScalaDoc for Seq

scala> dirty.distinct
res0: List[java.lang.String] = List(a, b, c)

更新。其他人建议使用Set而不是List。很好,但是请注意,默认情况下,该Set接口不保留元素顺序。您可能需要使用一组实施,明确维持秩序,如collection.mutable.LinkedHashSet


2
如果您有文件列表并且需要比较文件名的一部分怎么办?
臭氧

4
@ozone有趣的问题。也许最简单的方法是创建一个新 的type 映射Map[String, File],其中的键是目标文件名的一部分。构建完地图后,您可以调用values方法以获取Iterable值-各个键在构造上都是不同的。
Kipton Barros

@KiptonBarros和我认为您可以使用的groupBy成员来执行此操作scala.collection.Iterable[A]
路易·雅各布·勒贝尔

18

scala.collection.immutable.List现在有一种.distinct方法。

因此dirty.distinct现在可以调用而无需转换为Setor Seq


1
.distinct没有为定义scala.collection.Iterable[A]。因此,在这种情况下,您必须使用升级dirty到a SeqSet无论如何(即通过使用.toList.toSeq.toSet成员)才能使其正常工作。
路易·雅各布·勒贝尔

15

在使用Kitpon解决方案之前,请考虑使用a Set而不是a List,它可以确保每个元素都是唯一的。

由于大部分列表操作(foreachmapfilter,...)是集合和列表相同,改变收集可能是代码非常容易。


7

当然,首先使用Set是正确的方法,但是:

scala> List("a", "b", "a", "c").toSet.toList
res1: List[java.lang.String] = List(a, b, c)

作品。或者正像toSet它支持顺序 Traversable 接口。


1
我编辑你的答案,因为Set工具Traversable,不是Seq。区别在于Seq保证元素的顺序,而Traversable不能保证元素的顺序。
Kipton Barros 2011年

-3

inArr.distinct for每个println _


这会打印所需的输出,OP是否不要求返回它(大概是列表)?
RobP 2014年

-4

算法方式...

def dedupe(str: String): String = {
  val words = { str split " " }.toList

  val unique = words.foldLeft[List[String]] (Nil) {
    (l, s) => {
      val test = l find { _.toLowerCase == s.toLowerCase } 
      if (test == None) s :: l else l
    }
  }.reverse

  unique mkString " "
}

1
他有一个列表,而不是字符串。这不能回答问题。
Tim Gautier
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.