2016-04-21 54 views
0

如果我有如何在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)) 

轉換,但我想使功能適用於所有深度數組。 所以我試過

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

所以'測試包含一個二元陣列(含元組)IA陣列,然後一個元組; SA非常奇怪的數據結構,是不是真的正確 –

回答

0

。你可以做扁平化方式如下:??

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

謝謝你真是太棒了! – Ben

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))