【问题标题】:Uncurrying/tupling a multidimensional array in Scala?在 Scala 中对多维数组进行非currying/tupling?
【发布时间】:2013-03-03 21:05:44
【问题描述】:

假设我有一个例如二维数组,我将一些索引存储在元组中:

val testArray = Array.ofDim[Double](3, 4)
val ixs = (1,2)

我想直接使用这些元组,例如testArray(ixs)。但是,Function.tupled(testedArray _) 返回“_ 必须遵循方法;不能遵循 Array[Array[Double]]”。

这是因为Array 实际上不是Function3 的子类型吗? 如果是这样,如何绕过这个限制?我应该使用隐式来扩展 ArrayOps 还是类似的东西? 目前,我将数据存储在 Map 中作为一种解决方法。

【问题讨论】:

    标签: scala scala-collections scala-2.10


    【解决方案1】:

    数组数组不给予特殊处理;它们只是(某物)的数组。因此,没有通过元组访问它们的特殊方法。但正如您所建议的,您可以创建这样的方式。

    你可以

    implicit class ArrayOps2D[@specialized T](xss: Array[Array[T]]) {
      def apply(ij: (Int, Int)) = xss(ij._1)(ij._2)
      def apply(i: Int, j: Int) = xss(i)(j)
      def update(ij: (Int, Int), t: T) { xss(ij._1)(ij._2) = t }
      def update(i: Int, j: Int, t: T) { xss(i)(j) = t }
    }
    

    你可能会考虑做

    implicit class ArrayOps2D[T](val xss: Array[Array[T]]) extends AnyVal {
      def apply(ij: (Int, Int)) = xss(ij._1)(ij._2)
      def apply(i: Int, j: Int) = xss(i)(j)
      def update(ij: (Int, Int), t: T) { xss(ij._1)(ij._2) = t }
      def update(i: Int, j: Int, t: T) { xss(i)(j) = t }
    }
    

    但在我看来,这并不奏效。由于实施限制,您不能专门化 AnyVal。此外,如果您经常使用原语,前者可能会更好,因为它避免了对原语进行装箱(希望 JVM 可以处理避免对象创建),而如果您大部分时间都使用非原语,则后者效率更高(例如字符串),因为您没有(正式)创建对象。但是您的示例使用了原语。

    无论如何,如果您这样做,您将获得带有元组和成对参数的无缝双索引寻址(正如我所写的那样)。但是,您不能完全无缝地使用更新方法!它们大部分都可以工作,但它们不会自动提升数字类型。所以如果你有双打并且你写a(1,2) = 3它会失败,因为它没有找到update(Int, Int, Int)方法,并且不认为使用update(Int, Int, Double)。但是您可以通过转换(或者在这种情况下写3d)自己解决这个问题。

    【讨论】:

    • 感谢您全面讨论这两种方法之间的权衡。
    • 另外,你现在可以(Scala 2.10+)用值类“专门化”AnyVal,虽然在实现方面,它不像straightforward as simple "subclassing"
    • @TheTerribleSwiftTomato - 我不确定你的意思。你实际上不能在 2.10 中使用 specialized 关键字,我已经在“你可能会想到做”下介绍了通用的 unboxed-array-boxed-elements 版本。
    • 嘿,这里有点误会,尽管如此,由于我对 Scala 的了解不足 - 我不知道 specialized 关键字并假设您指的是一般的 OOP 术语。在这种情况下,是的,您提到的答案部分已经涵盖了这一点。
    • @TheTerribleSwiftTomato - 很公平。 (从技术上讲,它是一个注释,而不是一个关键字——我在上面说错了。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2013-11-27
    • 1970-01-01
    • 2019-11-26
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    相关资源
    最近更新 更多