【问题标题】:How to flatten a List of different types in Scala?如何在Scala中展平不同类型的列表?
【发布时间】:2010-12-16 18:50:13
【问题描述】:

我有 4 个元素:List[List[Object]](每个元素中的对象不同),我想压缩它们以便我可以拥有一个 List[List[obj1],List[obj2],List[obj3],List[obj4]]

我试图压缩它们,但我得到了一个嵌套列表,我无法对其应用 flatten,因为它说:没有隐式参数匹配参数类型。

我该如何解决这个问题?我应该尝试另一种方式还是有什么方法可以使扁平化工作?

我对 scala 有点陌生,所以这可能是一个愚蠢的问题:D 提前致谢! 克劳

【问题讨论】:

  • 谢谢大家 :) 我有点明白 flatten 方法并不是我想要的,我想我用 for 解决了这个问题。谢谢你的好建议:)

标签: list scala nested flatten


【解决方案1】:

例如考虑List.concat

List.concat(List(1), List(2,22), List(3))    // delivers List(1, 2, 22, 3)

【讨论】:

    【解决方案2】:

    对于一个嵌套列表flatten 会做:

    scala> List(List(1), List(2), List(3)).flatten
    res4: List[Int] = List(1, 2, 3)
    
    scala> List(List(List(1)), List(List(2)), List(List(3))).flatten
    res5: List[List[Int]] = List(List(1), List(2), List(3))
    

    对于多个嵌套列表,您可以:

    def flatten(ls: List[Any]): List[Any] = ls flatMap {
      case i: List[_] => flatten(i)
      case e => List(e)
    }
    
    val k = List(1, List(2, 3), List(List(List(List(4)), List(5)), List(6, 7)), 8)
    flatten(k)
    

    它打印List[Any] = List(1, 2, 3, 4, 5, 6, 7, 8)

    【讨论】:

      【解决方案3】:

      在 Scala 2.10.2 中

      scala> val foo = List(List(1), List("a"), List(2.3))
      foo: List[List[Any]] = List(List(1), List(a), List(2.3))
      
      scala> foo.flatten
      res0: List[Any] = List(1, 2, a, 2.3)
      

      工作正常,但是

      如果你喜欢跑步

      scala>  val foo = List(List(1,2), 2, List(2.3))
      foo: List[Any] = List(List(1, 2), 2, List(2.3))
      
      scala> foo.flatten
      <console>:9: error: No implicit view available from Any => scala.collection.GenTraversableOnce[B].
                    foo.flatten
      

      为此我编写函数

      scala> def flat(ls: List[Any]): List[Any]= ls flatten {
           |   case t: List[Any] =>  flat(t)
           |   case c => List(c)
           | }   
      flat: (ls: List[Any])List[Any]
      
      scala> flat(List(List(1,2),2,List(2.3)))
      res2: List[Any] = List(1, 2, 2, 2.3)
      

      【讨论】:

        【解决方案4】:

        在 Scala 2.9 之前

        根据您粘贴的错误,您似乎正在尝试调用嵌套列表本身的 flatten 实例方法。这需要隐式转换才能从 List 包含的任何类型中生成 Iterable 类型的东西。在您的情况下,编译器似乎找不到。

        使用来自List 单例对象的flatten,它不需要隐式参数:

        scala> val foo = List(List(1), List("a"), List(2.3))
        foo: List[List[Any]] = List(List(1), List(a), List(2.3))
        
        scala> List.flatten(foo)
        res1: List[Any] = List(1, a, 2.3)
        

        在 Scala 2.9 之后

        只需使用foo.flatten

        【讨论】:

        • 现在 (2.9.1) 已弃用。
        • @macias:你可以代替List.flatten()foo.flatten
        【解决方案5】:

        list1 zip list2一次只能压缩两个列表,返回值的类型签名是List[(A,B)]而不是List[List[obj1],List[obj2],List[obj3],List[obj4]]

        【讨论】:

          【解决方案6】:

          这个问题很模糊。你应该粘贴你所拥有的,而不是试图描述它。这将使每个人(包括您的)的生活更加轻松。

          下面的代码是一个基于假设的示例。

          scala> List(List(1))
          res0: List[List[Int]] = List(List(1))
          
          scala> List(List(2))
          res1: List[List[Int]] = List(List(2))
          
          scala> List(List(3))
          res2: List[List[Int]] = List(List(3))
          
          scala> List(List(4))
          res3: List[List[Int]] = List(List(4))
          
          scala> res0 ::: res1 ::: res2 ::: res3
          res4: List[List[Int]] = List(List(1), List(2), List(3), List(4))
          

          【讨论】:

            【解决方案7】:

            如果我们有一个例子,它会有所帮助。您的代码应类似于:

            val f = List(1, 2)
            val s = List(3, 4)
            val top = List(f, s)
            
            List.flatten(top) // returns List(1, 2, 3, 4)
            

            【讨论】:

              最近更新 更多