2016-04-21 5 views
0

wenn ichWie Funktion für flattern Paare von Arrays in Scala machen?

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

haben, und ich will diese konvertieren zu

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

Ich kann mit flatMap Funktion wie diese

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

konvertieren, aber ich möchte Funktion für alle Tiefe machen von Arrays. so habe ich versucht,

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

was ist das Problem ???

+2

So 'Test ist ia Array mit einer zwei-Element-Array (mit Tupeln), und dann einem Tupel das, ist ein sehr ungeradee Datenstruktur ist es wirklich richtig –

Antwort

0

. Sie können die folgende Art und Weise tun Abflachung:?

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

Thank dich so sehr!!! – Ben

0

Nun, ich habe eine Lösung, vielleicht nicht die beste, da es Nicht-Tail-Rekursion verwendet, die zu Problemen führen kann, wenn Sie eine Menge Daten haben. Auch sie geht davon aus, dass Sie nicht gemischt Tupeln und Arrays auf der gleichen Ebene haben (wie Array (1 -> 2, Array (2 -> 3)) Also, nur als Referenz:

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