1

我想转换一个数组数组。这可以通过以下方式完成:

var cal = Array.ofDim[Double](300, 10000);   
cal.foreach(x => x.transform(y => some_value))

问题是如何访问转换单元格的索引。例如:

cal.foreach(x => x.transform(y => x(y.index - 1) + 7))

我尝试使用 zipWithIndex:

cal.foreach(x => x.zipWithIndex.transform(y => (x(y._2) + 7, y._2)));

但这并没有改变“cal”值。

谢谢。

4

3 回答 3

4

后一个选项不起作用,因为您正在调用x.zipWithIndex,它返回一个新的元组集合,然后正在转换该集合。这不会对底层数组产生任何影响。

我想不出任何可以让您修改数组同时仍然可以访问索引的方法。但是,如果您可以采用更实用的返回新集合的样式,则可以执行以下操作:

val cal = Array.ofDim[Double](300, 10000) map { x =>
    x.zipWithIndex map (y => x(y._2) + 7)
};

事实上,由于cal在您的示例中是可变的,您可以通过重新分配来做同样的事情。并不是说如果可以避免可变变量,我会鼓励它。

于 2013-04-10T09:59:46.683 回答
2

要就地进行更新,您可以使用类似 java 的方式进行更新,如下所示:

for( y <- 0 until cal.length; 
     row <- cal( y );
     x <- 0 until row.length ) 
{
  row( x ) = some value // here you can get the indexes through (x, y)
}

// or

for( (row, y) <- cal.zipWithIndex; 
     x <- 0 until row.length ) 
{
  row( x ) = some value // here you can get the indexes through (x, y)
}
于 2013-04-10T10:09:34.780 回答
0

如果您在标准库中找不到函数,最简单的解决方案是编写您自己的函数,特别是如果它是一个简单的函数。在 Scala 中,函数作为参数并没有什么神奇的地方可以阻止你自己这样做。

隐式类甚至允许您模拟正常的调用约定。例如:

import scala.collection.mutable._

object Extensions {
  implicit class ExtMutSeq[T](val seq: Seq[T]) extends AnyVal {
    def transform_indexed(f: (T, Int) => T) {
      for (i <- 0 until seq.length) {
        seq(i) = f(seq(i), i)
      }
    }
  }
}

object Program extends App {
  import Extensions._
  val a = ArraySeq(1,2,3,4)
  a.transform_indexed((item, pos) => if (pos % 2 == 0) 0 else item)
  println(a)
}

(根据您的行的实际类型,您可能需要调整seq上面的类型。)

您可以获得抽象和重用的双重好处。抽象是因为它允许您将转换的概念与索引封装在一个地方,重用是因为您只需编写一次。而且因为它是短代码,所以没有必要依赖标准库。

于 2013-04-10T12:38:18.960 回答