简体   繁体   English

SortedSet 折叠类型不匹配

[英]SortedSet fold type mismatch

I have this code:我有这段代码:

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

I want to iterate over seq , delete duplicates (keep the first number) and keep order of the numbers.我想遍历seq ,删除重复项(保留第一个数字)并保持数字顺序。 My idea was to use a SortedSet as an acc.我的想法是使用SortedSet作为 acc。

But I am getting:但我得到:

Type mismatch:类型不匹配:
Required: String必需:字符串
Found: Any发现:任何

How to solve this?如何解决这个问题? (I also don't know how to convert SortedSet to Seq in the final iteration as I want distinct to return seq ) (我也不知道如何在最后一次迭代中将SortedSet转换为Seq ,因为我希望distinct返回seq

ps without using standard seq distinct method ps 不使用标准的seq distinct方法

Online code在线代码

You shouldn't use fold if you try to accumulate something with different type than container ( SortedSet != Int ) in your case.如果您尝试在您的案例中积累与容器( SortedSet != Int )不同类型的东西,则不应使用fold Look at signature fold :看看签名fold

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

it takes accumulator with type A1 and combiner function (A1, A1) => A1 which combines two A1 elements.它需要类型为A1的累加器和组合器 function (A1, A1) => A1 ,它组合了两个A1元素。

In your case is better to use foldLeft which takes accumulator with different type than container:在您的情况下,最好使用foldLeft ,它采用与容器不同类型的累加器:

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

it accumulates some B value using seed z and combiner from B and A to B .它使用种子z和从BAB的组合器累积一些B值。

In your case I would like to use LinkedHashSet it keeps the order of added elements and remove duplicates, look:在你的情况下,我想使用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)

and after folding just use toSeq折叠后只需使用toSeq

be careful, lambda _ + _ is just syntactic sugar for combiner:注意,lambda _ + _只是组合器的语法糖:

(linkedSet, nextElement) => linkedSet + nextElement

I would just call distinct on your Seq .我只想在你的Seq上调用distinct You can see in the source-code of SeqLike , that distinct will just traverse the Seq und skip already seen data:您可以在SeqLike的源代码中看到, 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
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM