scala中的数组更新(相当于NumPy广播分配)

时间:2017-06-15 20:23:43

标签: python arrays scala numpy variable-assignment

我正在学习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}}

但是,我仍然想知道是否有办法以更接近原始代码的方式编写它。 (没有对所有索引进行显式循环。)

是否存在一种方法,或许是用另一个数组的元素替换一个数组的全部内容?

1 个答案:

答案 0 :(得分:0)

scratch.copyToArray(arr)

请注意,它不会复制内部数组,因此,如果您的do_sthdo_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))