Reputation: 53
I tried to flatten the list of lists using the below code. When I put it on paper, it should work but I think I misinterpreted or am ignorant of how lists work. Could any one tell me where i went wrong.
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)
Upvotes: 2
Views: 1081
Reputation: 3325
You can actually pattern match deep into the structure:
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)
}
Upvotes: 0
Reputation: 35453
I made two minor changes to your example to get it working. The first was to use a generic (not the problem, but clears up the code a bit). The second was to use :::
instead of ::
in the case where the input list has more than one item. The ::
method prepends a single item to a List which is the type of items in the list. The :::
concatenates two lists together. Using a type of List[Any]
, you were not able to see that issue. But once I changed the type to T
, it was pretty clear where the issue was.
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)
}
}
Upvotes: 1
Reputation: 53829
Your flat
function just recreates its argument list so it can be dropped.
You simply need to concatenate the inside lists, using :::
:
def flatten(xss : List[List[_]]): List[Any] = xss match {
case Nil => Nil
case head :: tail => head ::: flatten(tail)
}
Upvotes: 1