在 Scala 中扁平化列表而不使用扁平化方法给出糟糕的结果



我试图使用以下代码扁平化列表。当我把它写在纸上时,它应该可以工作,但我认为我误解了列表或对列表的工作原理一无所知。谁能告诉我我哪里做错了。

val a = List(List(1,2,3),List(4,5,6),List(7,8,9))
def flatten(xss : List[List[Any]]) : List[Any] = {
  def flat(xs : List[Any]) : List[Any] = xs match {
    case Nil => Nil
    case head :: Nil=> head :: Nil
    case head :: tail => head :: flat(tail)
  }
  xss match {
    case Nil => Nil
    case head :: Nil => flat(head)
    case head :: tail => flat(head) :: flatten(tail)
  }
}
flatten(a)

您的flat函数只是重新创建其参数列表,以便可以将其删除。

您只需要使用:::连接内部列表:

def flatten(xss : List[List[_]]): List[Any] = xss match {
  case Nil => Nil
  case head :: tail => head ::: flatten(tail)
}

我对你的示例做了两个小的更改以使其正常工作。 首先是使用泛型(不是问题,但稍微清理了代码)。 第二种是在输入列表包含多个项目的情况下使用 ::: 而不是 :::: 方法将单个项附加到列表中,该列表是列表中的项类型。 :::将两个列表连接在一起。 使用某种类型的List[Any],您无法看到该问题。 但是一旦我将类型更改为T,就很清楚问题出在哪里了。

def flatten[T](xss : List[List[T]]) : List[T] = {
  def flat(xs : List[T]) : List[T] = xs match {
    case Nil => Nil
    case head :: Nil=> head :: Nil
    case head :: tail => head :: flat(tail)
  }
  xss match {
    case Nil => Nil
    case head :: Nil => flat(head)
    case head :: tail => flat(head) ::: flatten(tail)
  }
}

您实际上可以在结构深处进行模式匹配:

def flatten[T](xss: List[List[T]]): List[T] = xss match {
   case Nil => Nil
   case Nil :: tail => flatten(tail)
   case (innerHead :: innerTail) :: tail => innerHead :: flatten(innerTail :: tail)
}

最新更新