SortedSet 折叠类型不匹配

SortedSet fold type mismatch

我有这个代码:

def distinct(seq: Seq[Int]): Seq[Int] =
  seq.fold(SortedSet[Int]()) ((acc, i) => acc + i)

我想遍历 seq,删除重复项(保留第一个数字)并保持数字顺序。我的想法是使用 SortedSet 作为 acc.

但我得到:

Type mismatch:
Required: String
Found: Any

如何解决这个问题? (我也不知道如何在最后一次迭代中将 SortedSet 转换为 Seq,因为我希望将 distinct 转换为 return seq

p.s。不使用标准 seq distinct 方法

Online code

如果您尝试积累与您的容器类型不同的东西(SortedSet != Int),您不应该使用 fold。看签名fold:

def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1

它需要类型为 A1 的累加器和组合器函数 (A1, A1) => A1,它组合了两个 A1 元素。

在您的情况下,最好使用 foldLeft,它采用与容器不同类型的累加器:

def foldLeft[B](z: B)(op: (B, A) => B): B

它使用 种子 z 和从 BA 到 [=22= 的组合器累积一些 B 值].

在你的情况下,我想使用 LinkedHashSet 它保持添加元素的顺序并删除重复元素,看:

import scala.collection.mutable

def distinct(seq: Seq[Int]): Seq[Int] = {
  seq.foldLeft(mutable.LinkedHashSet.empty[Int])(_ + _).toSeq
}
distinct(Seq(7, 2, 4, 2, 3, 0)) // ArrayBuffer(7, 2, 4, 3, 0)
distinct(Seq(0, 0, 0, 0)) // ArrayBuffer(0)
distinct(Seq(1, 5, 2, 7)) // ArrayBuffer(1, 5, 2, 7)

折叠后只需使用 toSeq

小心,lambda _ + _ 只是组合器的语法糖:

(linkedSet, nextElement) => linkedSet + nextElement

我只想给你的 Seq 打电话 distinct。您可以在 SeqLike 的 source-code 中看到,distinct 将只遍历 Seq 并跳过已经看到的数据:

  def distinct: Repr = {
    val b = newBuilder
    val seen = mutable.HashSet[A]()
    for (x <- this) {
      if (!seen(x)) {
        b += x
        seen += x
      }
    }
    b.result
  }