如何沿2D数组的维度从1D数组中发散?

时间:2019-07-09 05:18:15

标签: arrays f#

我有一个2D数组,并且已经使用1D数组沿给定的维度计算了必要的更新(由于无法进行较早的计算,因此无法计算到该更新,因此较早的计算会覆盖所需的值)。因此,我想将更新复制到2D阵列中。乍一看,最明显的方法似乎是使用数组切片和Array.blit

我尝试了使用数组切片来提取相关维度,然后对其进行模糊处理的方法,但这并不会更新2D数组内部的值。我认为发生的事情是,当我制作切片时正在创建一个新的,单独的一维数组,并且将值映射到该新数组中,当然,当稍后将其删除它会超出范围。

我想你可以说我期望切片将返回2D数组的视图,该视图可用于blit函数调用,但是切片实际上返回了一个新数组,并将值复制到其中(我认为,切片是这样做的,我相信)。

当前,我正在使用一种变通方法,即创建2D数组,其中一个维度只有1个元素宽(因此有效地重新创建了1D数组),然后使用Array2D.blit。不过,我宁愿直接执行此操作,这既因为我觉得这很丑陋,又因为它在程序中的其他地方非常有用,因为我不能将一维数组声明为2D。

我的第一种方法:

let srcArray = Array.zeroCreate srcArrayLength
...  // do relevant computation
srcArray.[index] <- result
...  // finish computation
Array.blit srcArray 0 destArray.[index, *] 0 srcArrayLength

我目前的做法:

let srcArray = Array2D.zeroCreate 1 srcArrayLength
... // do relevant computation
srcArray.[0,index] <- result
...  // finish computation
Array2D.blit srcArray 0 0 destArray index 0 1 srcArrayLength

前一种方法对我的目标2D数组没有影响。后一种方法在我使用它的地方有效,但是正如我上面所说的那样,它并不好,并且不能在其他情况下使用,在这种情况下,我有一个锯齿状的2D数组(即'a[][]),我想将其剖开来自。

我该如何实现自己的目标?我想到了Span / Memory,但我不清楚在这里是否以及如何使用它们。另外,如果您能找到一种更好的方式来完成此工作而不涉及blit,那么我就是虚拟耳朵了。

1 个答案:

答案 0 :(得分:0)

在F#Foundation Slack的帮助下,我找到了一个很好的解决方案。由于没有人发布答案,因此我将其提出。

同时向我建议了Array.CopyBuffer.BlockCopy(请注意,这是.NET Array.Copy method,而不是F#-specific Array.copy)。 Array.Copy仍然抱怨数组类型不匹配,但是Buffer.BlockCopy忽略了所提供数组的维数,只是将指定数量的字节从一个位置复制到另一个位置。利用这一点并基于2D数组实际上以行优先顺序存储为1D数组(我相信与C相同)这一事实,很有可能相当干净地覆盖多维数组的最后一个维度。 / p>

我将代码从问题中的“当前方法”更新为以下内容:

let srcArray = Array.zeroCreate srcArrayLength
... //do relevant computation
srcArray.[index] <- result
... //finish computation
Buffer.BlockCopy(srcArray, 0, destArray, firstDimIndex * lengthOfSecondDim * sizeof<'a>, lengthOfSecondDim * sizeof<'a>

它不仅以我个人觉得比较整齐的方式完成了工作,而且还具有副作用,因为它明显比问题中所述的第二种方法快-我还没有运行基准来量化差异。