List 使用展平方法展平Scala中的列表而不使用out会产生不良结果

List 使用展平方法展平Scala中的列表而不使用out会产生不良结果,list,scala,scala-collections,flatten,List,Scala,Scala Collections,Flatten,我尝试使用下面的代码将列表展平。当我把它写在纸上的时候,它应该是有效的,但我认为我误解了或者不知道列表是如何工作的。谁能告诉我哪里出错了 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

我尝试使用下面的代码将列表展平。当我把它写在纸上的时候,它应该是有效的,但我认为我误解了或者不知道列表是如何工作的。谁能告诉我哪里出错了

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)
}

我对您的示例做了两个小改动,以使其正常工作。第一种是使用泛型(这不是问题,但会稍微清除代码)。第二种方法是在输入列表包含多个项目的情况下使用
::
而不是
方法将单个项目预先添加到列表中,该列表是列表中的项目类型。
将两个列表连接在一起。使用
列表[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)
}

我想你需要再想一想扁平化列表意味着什么,我倾向于使用的一个好技巧是用文字来表达它,因为通常有一个函数实现可以很好地匹配它。你想过使用内置的flatMap函数吗?我应该在不使用扁平化方法的情况下实现扁平化函数。甚至不应该使用::@johanandren。我知道扁平化列表意味着什么,更担心的是如何在Scala中实现功能,为此我编写了一个函数,通过扁平化函数处理内部列表。我应该实现扁平化函数,而不使用扁平化方法。甚至不应该使用:::这是非常有效的工作方式。你也可以看看我的代码,告诉我哪里出错了。同样从代码来看,当我用'head::Nil=>flatten(head)`替换第二个案例时,它确实会产生差异(错误)。不管怎样,它对列表中的最后一个值有什么不同。我开始知道head返回原语类型,而tail返回一个列表。类型不匹配是阻止我执行其他方法的一个问题。@Ram_-TU是的,类型泄露了错误。对于
List[T]
,:的左侧具有类型
T
,右侧具有类型
List[T]
。在原始版本中,您有
case head::tail=>flat(head)::flant(tail)
,但是
flat(head)
的返回类型是一个列表,而不是一个项目。