Trong Scala, làm cách nào để loại bỏ các bản sao khỏi danh sách?


94

Giả sử tôi có

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

Có một hoạt động danh sách trả về "a", "b", "c"

Câu trả lời:


175

Hãy xem ScalaDoc cho Seq ,

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

Cập nhật . Những người khác đã đề xuất sử dụng Sethơn là List. Điều đó tốt, nhưng hãy lưu ý rằng theo mặc định, Setgiao diện không bảo toàn thứ tự phần tử. Bạn có thể muốn sử dụng thực hiện Set rằng rõ ràng không giữ gìn trật tự, chẳng hạn như collection.mutable.LinkedHashSet .


2
Điều gì sẽ xảy ra nếu bạn có một danh sách các tệp và cần so sánh trên một số thứ như một phần của tên tệp?
ozone

4
@ozone Câu hỏi thú vị. Có lẽ cách đơn giản nhất là để tạo ra một mới bản đồ kiểu Map[String, File], nơi các phím là một phần của tên tập tin quan tâm. Khi bản đồ được xây dựng, bạn có thể gọi valuesphương thức để nhận một Iterabletrong các giá trị - tất cả các khóa sẽ khác nhau theo cấu trúc.
Kipton Barros 19/12/12

@KiptonBarros và tôi nghĩ bạn có thể làm điều này bằng cách sử dụng groupBythành viên của scala.collection.Iterable[A].
Louis-Jacob Lebel

18

scala.collection.immutable.Listbây giờ có một .distinctphương pháp.

Vì vậy, dirty.distinctbây giờ có thể gọi mà không cần chuyển đổi thành Sethoặc Seq.


1
.distinctkhông được xác định cho scala.collection.Iterable[A]. Vì vậy, trong trường hợp đó, bạn sẽ phải sử dụng nâng cấp dirtyđến một Seqhoặc một Setanyways (ví dụ bằng cách sử dụng một trong hai .toList, .toSeqhoặc .toSetthành viên) cho việc này để làm việc.
Louis-Jacob Lebel

15

Trước khi sử dụng giải pháp của Kitpon, hãy nghĩ đến việc sử dụng một Setthay vì a List, nó đảm bảo mỗi phần tử là duy nhất.

Như hầu hết các hoạt động danh sách ( foreach, map, filter, ...) là như nhau cho bộ và danh sách, thay đổi bộ sưu tập có thể rất dễ dàng trong các mã.


7

Tất nhiên, sử dụng Set ngay từ đầu là cách làm đúng, nhưng:

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

Làm. Hoặc chỉ toSetvì nó hỗ trợSeq Traversable giao diện.


1
Tôi đã chỉnh sửa câu trả lời của bạn vì nông Setcụ Traversable, không phải Seq. Sự khác biệt là Seqđảm bảo một thứ tự cho các phần tử, trong khi Traversablethì không.
Kipton Barros

-3

inArr.distinction foreach println _


điều này sẽ in ra kết quả mong muốn, không phải OP yêu cầu trả lại nó (có lẽ là một Danh sách)?
RobP

-4

Cách thuật toán ...

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
Anh ấy có một danh sách, không phải một chuỗi. Điều này không trả lời câu hỏi.
Tim Gautier
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.