在Scala上映射数组数组

时间:2017-10-15 10:31:21

标签: arrays scala

我有一个数组

val L = Array((1,Array("one", "two")), (2, Array("one", "three")))

我可以做这个操作

val LL = L.map({case (s,Array(s1,s2))=>(s1,s2,1)})

我想做同样的事情,但是使用不确定数量的元素的数组。例如 : val L = Array((1,Array("one", "two", "three", "four")), (2, Array("one", "three")))。这只是一个例子,所以基本上我想要一个适用于任何数组的代码,无论它有多少元素。

编辑:我想我发现了一种简单的方法。举个例子:

val L = Array((1,Array("one", "two", "three")), (2, Array("one", "three")))
val LL = L.flatMap({case (s,contents)=>(contents.map(s=>(s,1)))})

而不是(s1,s2)我只是使用名称​​ contents 来概括它,然后在flatMap中映射内部数组 contents

1 个答案:

答案 0 :(得分:0)

使用Java反射的解决方案:

println(
  Array((1, Array("one", "two", "three", "four")), (2, Array("one", "three")))
    .map(_._2)
    .map(arr => {
      val arr1 = new Array[Object](arr.length + 1)
      Array.copy(arr, 0, arr1, 0, arr.length)
      arr1(arr.length) = 1.asInstanceOf[Object]
      arr1
    })
    .map(arrayToTuple)
    .deep
) 
// Array((one,two,three,four,1), (one,three,1))

def arrayToTuple[A <: Object](arr: Array[A]): Product = {
  val clazz = Class.forName("scala.Tuple" + arr.length)
  clazz.getConstructors.apply(0).newInstance(arr: _*).asInstanceOf[Product]
}

基于answer

仅当内部数组的长度为&lt; = 21时才有效。