2015-04-22 69 views
2

我试图使用下面的代码展开列表的列表。当我把它放在纸上时,它应该起作用,但我认为我误解了或者对列表的工作方式一无所知。任何人都可以告诉我我错了哪里。在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) 
+0

我认为你需要采取另一种思维会话什么压扁列表意味着,一个好的技巧我倾向于使用的表达出来换句话说,因为经常有一个功能实现匹配那么好。 – johanandren

+0

你有没有想过使用内置的flatMap函数? – Leon

+0

我应该实现扁平化功能而不使用扁平化方法。即使不应该使用::: – user64287

回答

0

实际上,你可以模式匹配深入到结构:

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

这是执行工作的非常有效的方式。你还可以看看我的代码,并告诉我哪里出了问题。同样从代码中,当我用'head :: Nil => flatten(head)'替换第二个case时,它确实会产生差异(错误)。无论如何,它对列表中的最后一个值有什么不同。 – user64287

+0

我知道头返回原始类型,作为尾部返回一个List。类型不匹配是阻止我执行其他方法的一个问题。 – user64287

+0

@Ram_TU是的,类型给了错误。对于'List [T]','::'的左边有'T'类型,右边有'List [T]'类型。在你的原始版本中,你有'case head :: tail => flat(head):: flatten(tail)',但是flat(head)的返回类型不是一个单独的列表。 – Tilo

1

您的flat函数只是重新创建了它的参数列表,因此它可以被删除。

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

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

我做了两个小的改动你的榜样,使其能工作。第一个是使用通用的(不是问题,但清除了一些代码)。第二种是在输入列表具有多个项目的情况下使用:::而不是::::方法将单个项目预加到列表中,该列表是列表中项目的类型。 :::将两个列表连接在一起。使用一种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) 
    } 
} 
+0

我应该实现扁平化功能而不使用扁平化方法。即使不应该使用::: – user64287