[英]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
似乎还有方法wrap
和newArray 。 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.