我正在学习Scala,现在我正在将一段代码从Python翻译成Scala。
我有两个大致类似的功能:
arr[...] = scratch
除了for (x <- 0 until width) for (y <- 0 until height) arr(y)(x) = scratch(y)(x)
部分之外,一切都很好。我所知道的最接近的等价物就像是def innerFunction(arr : Array[Int]) : Array[Int] =
{
val scratch = Array.fill[Int](height, width)(0)
do_sth(arr, scratch)
do_sth_else(arr, scratch)
return scratch
}
def outerFunction() =
{
var arr = Array.fill[Int](height, width)(0)
for (_ <- 0 until its)
arr = innerFunction(arr)
// do other things...
}
,但它看起来很丑陋而且不太接近最佳。
所以,我已经做了一个解决方法,将赋值转移到外部函数并使用可变引用:
{{1}}
但是,我仍然想知道是否有办法以更接近原始代码的方式编写它。 (没有对所有索引进行显式循环。)
是否存在一种方法,或许是用另一个数组的元素替换一个数组的全部内容?
答案 0 :(得分:0)
scratch.copyToArray(arr)
请注意,它不会复制内部数组,因此,如果您的do_sth
和do_sth_else
执行scratch(i) = arr(j)
之类的操作,则无法按预期工作。对于这种情况,你需要一个循环,但它可以更简单:
for (i <- 0 until height) scratch(i).copyToArray(arr(i))
然而,你的第二个解决方案更好。它删除了不必要的额外工作(复制数组)和它删除了不需要的副作用(包括前一段中的问题!)(编辑:这是错误的;例如,如果你do scratch(0) = arr(0); scratch(1) = arr(0)
我认为你的Python代码将在下一步中以arr(0)
和arr(1)
中的相同内容结束不同的数组,但Scala代码将对同一个数组进行两次引用)。您也可以删除var
:
def outerFunction() =
(0 until its).foldLeft(Array.fill(height, width)(0)) { (arr, _) => innerFunction(arr) }
或
def outerFunction() =
Function.chain(Stream.fill(its)(innerFunction _)).apply(Array.fill(height, width)(0))