如何在Scala中为flatten对阵列创建函数?

时间:2016-04-21 05:41:34

标签: scala

如果我有

scala> test
res3: Array[java.io.Serializable] = Array(Array((AA,BB), (CC,DD)), (EE,FF))

我希望将其转换为

Array[(Any, Any)] = Array((AA,BB), (CC,DD), (EE,FF))

我可以使用像这样的flatMap函数进行转换

scala> val test2 = test.flatMap{
 | case (a,b) => Array((a,b))
 | case i:Array[Any] => i.flatMap{
 | case (a,b)=> Array((a,b))}
 | }
test2: Array[(Any, Any)] = Array((AA,BB), (CC,DD), (EE,FF))

但是我想为All depth of Arrays创建函数。 所以我试过

scala> def flatArray(array: Array[Any]): Array[(Any,Any)] ={
 | array.flatMap{
 | case (a,b) => Array((a,b))
 | case i:Array[Any] => flatArray(i)
 | }
 | }
 scala> val test2 = flatArray(test)
<console>:9: error: type mismatch;
 found   : Array[java.io.Serializable]
 required: Array[Any]
 Note: java.io.Serializable <: Any, but class Array is invariant in type T.
 You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10)
   val test2 = flatArray(test)
                         ^

问题是什么?

2 个答案:

答案 0 :(得分:0)

好吧,我有一个解决方案,也许不是最好的解决方案,因为它使用非尾递归,当你有大量数据时可能会导致问题。此外,它假设您没有在同一级别上混合元组和数组(如数组(1 - > 2,数组(2 - > 3))。所以,仅供参考:

import scala.collection.mutable.ArrayBuffer

val a: Array[Any] =
  Array(
    Array(1 -> 2, 2 -> 3),
    Array(
      Array(7 -> 1, 8 -> 3),
      Array(
        Array(1 -> 4, 5 -> 6, 12 -> 5),
        Array(3 -> 4)
      )
    )
  )

def flattenImpl(arr: Array[Any], acc: ArrayBuffer[(Int, Int)]): Array[(Int, Int)] = {
  arr.headOption match {
    case None => acc.toArray
    case Some((a: Int, b:Int)) => flattenImpl(arr.tail, acc :+ a -> b)
    case Some(a: Array[Any]) => flattenImpl(a, acc ++ flattenImpl(arr.tail, acc))
  }
}

def flatten(arr: Array[Any]): Array[(Int, Int)] = flattenImpl(arr, ArrayBuffer())

val res = flatten(a)

res: Array[(Int, Int)] = Array((3,4), (1,4), (5,6), (12,5), (7,1), (8,3), (1,2), (2,3))

答案 1 :(得分:0)

您可以通过以下方式进行展平:

def flatten(arr:Array[Any]):Array[(Any,Any)] = 
  arr.flatMap {
    case (a,b) => Array((a,b))
    case v:Array[Any] => flatten(v)
}