当某些元素不是数组时,在Scala 2.8中展平数组

当某些元素不是数组时,在Scala 2.8中展平数组,scala,Scala,如果我有 var a = Array(Array(1, 2), 3, Array(4,5,6)) 我想把这个转换成 Array(1, 2, 3, 4, 5, 6) 最简单的方法是什么?中给出的列表有一个解决方案 但它不适用于阵列 我也试过了 def flatArray(a:Array[Any])= a.map(x => x match { case ar:Array[_] => ar; case _ => Array(x) } ) 但是输出的类型是ArraySeq,我无法

如果我有

var a = Array(Array(1, 2), 3, Array(4,5,6))
我想把这个转换成

Array(1, 2, 3, 4, 5, 6)
最简单的方法是什么?中给出的列表有一个解决方案 但它不适用于阵列

我也试过了

def flatArray(a:Array[Any])= a.map(x => x match { case ar:Array[_] => ar; case _ => Array(x) } )
但是输出的类型是
ArraySeq
,我无法看到如何将其转换为
Array

def flatArray[T : ClassManifest](a:Array[Any]) = 
  a.flatMap{
    case ar:Array[T] => ar
    case x: T => Array(x) 
  }
我也尝试过使用#展平方法,但在NPE上失败了

更新:回答Jus12的问题:

def flatArray[T : Manifest](a:Array[Any]) = 
  a.flatMap{
    case ar: Array[_] if ar.getClass.getComponentType == manifest[T].erasure => ar.asInstanceOf[Array[T]];
    case x => Array(x.asInstanceOf[T])
  }
当然,整个解决方案不是类型安全的。原因是为了适应编译器的类型推断,它将
数组(数组(1,2),3,数组(4,5,6))
推断为
数组[Any]
。准确的类型是“由
Int
array[Int]
组成的数组”,但这是不可能的。要做的是创建一个由任意元素组成的数组,其中每个元素都是
or[Int,array[Int]]
,并使用该数组:

object EitherView {
  type ||[A, B] = Either[A, B]
  // convenience of definition functions
  private def l[A,B](a: A): ||[A,B] = Left(a)
  private def r[A,B](b: B): ||[A,B] = Right(b)

  // implicit defs - stuttering-or
  implicit def aToOr2[A,B](a: A): A || B = l(a)
  implicit def bToOr2[A,B](b: B): A || B = r(b)
  implicit def aToOr3[A,B,C](a: A): A || B || C =  l(l(a))
  implicit def bToOr3[A,B,C](b: B): A || B || C = l(r(b))
  implicit def aToOr4[A,B,C,D](a: A): A || B || C || D = l(l(l(a)))
  implicit def bToOr4[A,B,C,D](b: B): A || B || C || D =  l(l(r(b)))
  implicit def aToOr5[A,B,C,D,E](a: A): A || B || C || D || E = l(l(l(l(a))))
  implicit def bToOr5[A,B,C,D,E](b: B): A || B || C || D || E = l(l(l(r(b))))
  // more? ...

}

import EitherView._

type CompoundArray[T] = Array[T || Array[T]]

object CompoundArray {
  def apply[T](elems: (T || Array[T])*) = elems.toArray
}

def flatArray[T : Manifest](a:CompoundArray[T]) = {
  a.flatMap{
    case Left(x) => Array(x)
    case Right(x) => x
  }
}
见:

scala>vala=CompoundArray[Int](数组(1,2,3,4,5,6))
a:Array[EitherView.| |[Int,Array[Int]]]=Array(右)([I@1364b53),左(3),右([I@18b62e0))
scala>flatArray(a)
res0:Array[Int]=数组(1,2,3,4,5,6)
scala>flatArray(复合数组[字符串](数组(“hi”),“bye”))
res4:Array[String]=数组(您好,再见)
scala>flatArray(复合数组[String](数组(“hi”),3))
:13:错误:类型不匹配;
发现:Int(3)
必需:EitherView.| |[String,Array[String]]
平面阵列(复合阵列[字符串](阵列(“hi”),3))
^

注意:EithView的最初想法是@Mitch Blevins:

类似于IttayD,没有类清单,结果是数组[Any]

    scala> a.flatMap{
     |          case ar: Array[_] => ar
     |          case x => List(x)
     | }
    res4: Array[Any] = Array(1, 2, 3, 4, 5, 6)

如果示例是典型的,则返回Array[Int]:a.flatMap{case ar:Array[Int]=>ar;case x:Int=>List(x)}这要好得多。我永远无法理解类清单。在我的实际代码中,它是Int和其他类型的混合体,所以Array[Any]是我一直在寻找的。也感谢thoredge提供的解决方案。代码将返回一个对象数组,因此您将对其使用装箱和拆箱,并且无法将其传递给期望数组[Int]的函数.My solution返回一个int数组,可以在其他情况下使用。您不需要对ClassManifest过于在意。只需复制&paste@IttayD:我在您的解决方案中收到“未检查的警告”(使用ClassManifest)。这正常吗?谢谢你的解决方案。我收到了上述未检查的警告,因此我将使用Anwar Rizal建议的解决方案。有人能建议一种方法来解决上述解决方案中的类型擦除警告吗?这是我得到的:“警告:类型模式数组中的抽象类型T[T]未选中,因为它已通过擦除案例ar:Array[T]=>ar“感谢更新的解决方案。我希望会有更简单的解决方案。您能给我指一下
EitherView
的原始参考吗?
    scala> a.flatMap{
     |          case ar: Array[_] => ar
     |          case x => List(x)
     | }
    res4: Array[Any] = Array(1, 2, 3, 4, 5, 6)