使用迭代器时类型不匹配

问题描述 投票:1回答:1

当我运行以下代码时出现此错误 - 类型不匹配,发现:scala.collection.immutable.IndexedSeq [Int] required:Range

我哪里错了?

职能 -

def calcRange(i: Int, r: List[Range]):List[Range] = r match {
   case List() => List(new Range(i,i+1,1))

   case r1::rs =>
        if (r1.start-1==i) {new Range(i,r1.end,1):: rs; }

        else if(r1.end==i){new Range(r1.start,r1.end+1,1)::rs}

        else {r1::calcRange(i,rs)}
}

def recurseForRanges(l: Iterator[Int]):List[Range] = {
   var ans=List[Range]()
   while(l.hasNext){
       val cur=l.next;
       ans=calcRange(cur,ans)
    }
   ans
}

def rangify(l: Iterator[Int]):Iterator[Range] = recurseForRanges(l).toIterator

驱动程序代码

def main(args: Array[String]) {

    val x=rangify( List(1,2,3,6,7,8).toIterator ).reduce( (x,y) => x ++ y)      
/** This line gives the error -type mismatch, 
found : scala.collection.immutable.IndexedSeq[Int] required: Range */
}
scala
1个回答
4
投票

你可以查看文档:

++[B](that: GenTraversableOnce[B]): IndexedSeq[B]

++返回IndexedSeq,而不是另一个RangeRange不能有“洞”。

修复它的一种方法是在减少之前将Ranges更改为IndexedSeqs。这使Range向上倾斜,以便reduce可以起作用

(IndexedSeq[Int], IndexedSeq[Int]) => IndexedSeq[Int]

因为现在需要

(Range, Range) => Range

++实际上返回IndexedSeq[Int]而不是Range因此类型错误。

val x = rangify(List(1, 2, 3, 6, 7, 8).iterator).map(_.toIndexedSeq).reduce(_ ++ _)

您也可以通过注释类型执行此类转换:

val it: Iterator[IndexedSeq[Int]] = rangify(List(1,2,3,6,7,8).iterator)
val x = it.reduce(_ ++ _)

请注意,您的代码可以简化,不需要vars

def calcRange(r: List[Range], i: Int): List[Range] = r match {
   case Nil =>
      Range(i, i + 1) :: Nil
   case r1 :: rs =>
      if (r1.start - 1 == i)
        Range(i, r1.end) :: rs
      else if (r1.end == i) 
        Range(r1.start, r1.end + 1) :: rs
      else 
        r1 :: calcRange(rs, i)
}

def recurseForRanges(l: Iterator[Int]): List[Range] = {
   l.foldLeft(List.empty[Range])(calcRange)
}

def rangify(l: Iterator[Int]): Iterator[Range] = recurseForRanges(l).iterator

val x = rangify(List(1,2,3,6,7,8).iterator).map(_.toIndexedSeq).reduce(_ ++ _)

解释一下我用它做了什么:

Range有一个工厂方法,你不需要new关键字,你不需要指定by值,因为1是默认值。你也不需要分号。

你在recurseForRanges做的基本上是foldLeft所做的,我只是在calcRange中交换了参数,它可以直接传递给foldLeft

© www.soinside.com 2019 - 2024. All rights reserved.