我想转换一个数组数组。这可以通过以下方式完成:
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”值。
感谢。
答案 0 :(得分:4)
后一个选项不起作用,因为您正在调用x.zipWithIndex
,它返回一个新的元组集合,然后转换该集合。这对底层数组没有任何影响。
我无法想象任何允许你在仍然可以访问索引的同时修改数组的东西。但是,如果您可以采用更具功能性的方式返回新集合,则可以执行以下操作:
val cal = Array.ofDim[Double](300, 10000) map { x =>
x.zipWithIndex map (y => x(y._2) + 7)
};
事实上,由于cal
在您的示例中是可变的,因此您可以通过重新分配来执行相同的操作。如果它可以完全避免,我不会鼓励变量变量。
答案 1 :(得分:2)
要进行适当的更新,您可以使用以下java-ish方式进行更新:
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)
}
答案 2 :(得分: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
的类型。)
您将获得抽象和重用的双重好处。抽象,因为它允许您在一个地方用索引封装转换的概念,重用,因为您只需要编写一次。而且因为它是短代码,所以不必依赖标准库。