简体   繁体   English

使用任意类型创建三维数组并在Scala中映射

[英]Creating three dimensional Array with arbitrary type and map in Scala

When we have an Array of arbitrary type X in Scala and we try to do a double nest to each of its values using map (that is, turning [1,2,3] into [[[1]],[[2]],[[3]]] ), we get a java.lang.ArrayStoreException . 当我们在Scala中有一个任意类型X的数组时,我们尝试使用map对每个值进行双重嵌套(即将[1,2,3]转换为[[[1]],[[2]],[[3]]] ),我们得到一个java.lang.ArrayStoreException Code below is a minimal failing example: 下面的代码是一个最小的失败示例:

import scala.reflect.ClassTag

def doubleNest[X: ClassTag](values: Array[X]): Array[Array[Array[X]]] = {
  values map { value =>
    Array(Array(value))
  }
}

doubleNest(Array(1,2,3))

What is more, error seems to arise when turning [[1],[2],[3]] into [[[1]],[[2]],[[3]]] . 更重要的是,将[[1],[2],[3]]转换为[[[1]],[[2]],[[3]]]时似乎出现了错误。 Code below is a minimal failing example (error happens in the second map ): 下面的代码是一个最小的失败示例(第二个map发生错误):

import scala.reflect.ClassTag

def doubleNest[X: ClassTag](array: Array[X]): Array[Array[Array[X]]] = {
  val nested = array map { value =>
    Array(value)
  }

  nested map { arr =>
    Array(arr)
  }
}

doubleNest(Array(1,2,3))

Why does this happen? 为什么会这样?

It seems that Scala doesn't like making nested generic arrays directly. 似乎Scala不喜欢直接制作嵌套的通用数组。 Even this fails: 即使这样也失败了

def foo[T: ClassTag](t: T) = Array(Array(t))
foo(1) // java.lang.ClassCastException: java.base/[Ljava.lang.Object; cannot be cast to [[I

(In this case, it's probably because ClassTag looks at the erased class, so Array.apply does the same, and it creates an Array[Array[Object]] instead of Array[Array[T]] .) (在这种情况下,可能是因为ClassTag查看已擦除的类,因此Array.apply执行相同操作,并创建一个Array[Array[Object]]而不是Array[Array[T]] 。)

It also appears that ClassTag has the methods wrap and newArray for this purpose. 为了这个目的, ClassTag似乎还有方法wrapnewArray So, you can use some ugliness involving implicitly[ClassTag[X]].wrap.wrap.newArray(array.length) to get the job done, or you can do this, which seems to work by never directly asking it to create a nested array: 所以,你可以使用一些涉及implicitly[ClassTag[X]].wrap.wrap.newArray(array.length)来完成工作,或者你可以这样做,这似乎工作从来没有直接要求它创建一个嵌套数组:

import scala.reflect.ClassTag

def nest[C: ClassTag](arr: Array[C]) = arr.map(Array(_))

def doubleNest[X: ClassTag](array: Array[X]): Array[Array[Array[X]]] =
  nest(nest(array))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM