【问题标题】:6- or more dimensional Arrays in ScalaScala 中的 6 维或更多维数组
【发布时间】:2015-07-30 02:56:08
【问题描述】:

我正在研究 Scala 中的多维数组,并遇到了一些创建多维数组的简单方法。即:

val my3DimensionalArray = Array.ofDim[Int](3,4,5) //array with dimensions 3 x 4 x 5

甚至

val myFilledArray = Array.fill[Int](3,4,5)(0) //Array of same dimension filled with 0's

但这仅适用于 1 - 5 维数组:

val my6DimensionalArray = Array.ofDim[Int](3,3,3,3,3,3) //Error

那么人们通常如何处理创建更高维度的阵列?这是留给 3rd 方库来实现,还是 Scala 鼓励我们使用其他数据结构来代替高维数组?

【问题讨论】:

  • 你需要一个 6 维数组来做什么?这不是人们经常需要的东西。
  • 我实际上并没有考虑特定的用例 - 我只是想知道完整性,以防出现问题。

标签: arrays scala multidimensional-array n-dimensional


【解决方案1】:
// create array of 5-dim-array => 6 dim array
Array.tabulate(3)(_ => Array.ofDim[Int](3,3,3,3,3)) 

Array.ofDim 实现使用此模式。见https://github.com/scala/scala/blob/v2.11.6/src/library/scala/Array.scala#L216-234

【讨论】:

  • 感谢您的回答!这同样适用于小尺寸(6 或 7 左右),但对于 30 维来说,这不是很笨重吗? Array.tabulate(3)(_ => Array.tabulate(3)(_ => Array.tabulate(3) => .....
  • @JoshLemer 听起来 @tailrec 是你的朋友
  • @Daenyth 实际上我只是在玩弄一个玩具递归实现,但不确定是否可行,因为每个递归调用都会返回不同的类型。例如def highDimArray(n: Int*) = if(n.length == 5) Array.ofDim[Int](n(0),n(1), ... , n(4) ) else Array.tabulate(n.head)(_ => highDimArray(n.tail: _*)) ..似乎在每个递归级别都不起作用,返回不同的类型(Array[Array[Int]]]、Array[Array[Int]] 或 Array[Int] 等),所以没有办法定义返回类型吧?
  • 你需要一个像Free或者List这样的自递归类型
  • 我认为对 30 维数组的需求非常少见,因此笨重并不重要。我想不出一个使用这么多维度而不基本上是对树/图的不良模拟的用例。
【解决方案2】:

如果您真的想要任意数量的维度,您通常使用一个平面数组和第二个数组,该数组按维度索引以获取您想要的元素。所以,例如,

class MultiArray(dims: Array[Int]) {
  private val array = new Array[Double](dims.product)
  private def arrayIndex(index: Array[Int]) = {
    var i = index.length - 1
    var k = index(i)
    var n = 1
    while (i > 0) {
      n *= dims(i)
      k += n * index(i-1)
      i -= 1
    }
    k
  }
  def apply(index: Array[Int]) = array(arrayIndex(index))
  def update(index: Array[Int], value: Double) {
    array(arrayIndex(index)) = value
  }
}

将是一个开始。有各种各样的数学库可以做这种事情(IIRC Apache Commons Math 确实我不能很快找到一个 Java 数学库,但是ImgLib2 对图像数据使用了类似的技术(他们确实本地分块也))。这并不是一件真正有用的事情,这就是为什么您倾向于在数学库中找到它。

【讨论】:

  • 我没听懂你的最后一句话。我还发现平面阵列非常有用。你能澄清一下吗?
  • @ziggystar - 在尝试进行快速任意维数学运算时,打包成平面数组最有用。对于一般的非数学算法,如果您需要多个维度,则几乎没有理由不使用实际的数组数组。
  • 好的,明白你的意思。我查了 Commons Math,找不到多维度数组的实现,你能确认一下吗?
  • @ziggystar - 嗯,你是对的。我在想 C++ 库,也许吧?我检查的所有 Java 库都没有这样做。
猜你喜欢
  • 1970-01-01
  • 2012-12-01
  • 2016-01-20
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多