Scala flatten List

后端 未结 5 1704
無奈伤痛
無奈伤痛 2020-12-29 11:13

I want to write a function that flats a List.

object Flat {
  def flatten[T](list: List[T]): List[T] = list match {
    case Nil => Nil
    case head :: N         


        
相关标签:
5条回答
  • 2020-12-29 11:19

    You don't need to nest your match statements. Instead do the matching in place like so:

      def flatten(xs: List[Any]): List[Any] = xs match {
        case Nil => Nil
        case (head: List[_]) :: tail => flatten(head) ++ flatten(tail)
        case head :: tail => head :: flatten(tail)
      }
    
    0 讨论(0)
  • 2020-12-29 11:21

    My, equivalent to SDJMcHattie's, solution.

      def flatten(xs: List[Any]): List[Any] = xs match {
        case List() => List()
        case (y :: ys) :: yss => flatten(y :: ys) ::: flatten(yss)
        case y :: ys => y :: flatten(ys)
      } 
    
    0 讨论(0)
  • 2020-12-29 11:34

    If someone does not understand this line of the accepted solution, or did not know that you can annotate a pattern with a type:

    case (head: List[_]) :: tail => flatten(head) ++ flatten(tail)
    

    Then look at an equivalent without the type annotation:

    case (y :: ys) :: tail => flatten3(y :: ys) ::: flatten3(tail)
    case Nil :: tail => flatten3(tail)
    

    So, just for better understanding some alternatives:

    def flatten2(xs: List[Any]): List[Any] = xs match {
      case x :: xs => x match {
        case y :: ys => flatten2(y :: ys) ::: flatten2(xs)
        case Nil => flatten2(xs)
        case _ => x :: flatten2(xs)
      }
      case x => x
    }
    
    def flatten3(xs: List[Any]): List[Any] = xs match {
      case Nil => Nil
      case (y :: ys) :: zs => flatten3(y :: ys) ::: flatten3(zs)
      case Nil :: ys => flatten3(ys)
      case y :: ys => y :: flatten3(ys)
    }
    
    val yss = List(List(1,2,3), List(), List(List(1,2,3), List(List(4,5,6))))
    flatten2(yss) // res2: List[Any] = List(1, 2, 3, 1, 2, 3, 4, 5, 6) 
    flatten3(yss) // res2: List[Any] = List(1, 2, 3, 1, 2, 3, 4, 5, 6) 
    

    By the way, the second posted answer will do the following, which you probably don't want.

    val yss = List(List(1,2,3), List(), List(List(1,2,3), List(List(4,5,6))))
    flatten(yss) // res1: List[Any] = List(1, 2, 3, List(), 1, 2, 3, 4, 5, 6) 
    
    0 讨论(0)
  • 2020-12-29 11:42
      def flatten(ls: List[Any]): List[Any] = ls flatMap {
        case ms: List[_] => flatten(ms)
        case e => List(e)
      }
    
    0 讨论(0)
  • 2020-12-29 11:43

    By delete line 4

    case head :: Nil => List(head)
    

    You will get right answer.

    Think about the test case

    List(List(List(1)))
    

    With line 4 last element in list will not be processed

    0 讨论(0)
提交回复
热议问题