【问题标题】:Why does Array2D not have a fold operation?为什么 Array2D 没有折叠操作?
【发布时间】:2015-04-26 04:13:58
【问题描述】:

我刚刚遇到一个案例,在 Array2D 上使用 fold/foldi 方法会很有用,我想知道,如果有原因,为什么 Array2D 没有它们。

由于我的 array2d 非常庞大,我不想先将其转换为其他格式。

这仅仅是一个罕见的用例还是有技术原因,为什么没有添加这些方法?或者有没有办法在不接触数组中的数据的情况下实现同样的效果(如移动它)?

【问题讨论】:

    标签: f#


    【解决方案1】:

    我认为在标准Array2D 模块中拥有这个功能会非常有用。您可以为the Visual F# repository 开一个问题并帮助我们添加它:-)。

    除了@scrwtp 写的,你还可以使用更直接的可变实现。对于像这样的基本功能,我认为使用突变很好,而且会更快一些:

    let foldi (folder: int -> int -> 'S -> 'T -> 'S) (state: 'S) (array: 'T[,]) =
        let mutable state = state
        for x in 0 .. Array2D.length1 array - 1 do
            for y in 0 .. Array2D.length2 array - 1 do
                state <- folder x y state (array.[x, y])
        state
    

    【讨论】:

      【解决方案2】:

      我不认为Array2D 没有在标准中提供这些功能有什么特别的原因,因为它确实有map/mapi。无论如何,使用锯齿状数组可能会更好地处理您想要处理多维数组的用例,因此几乎没有添加它们的动机。

      你没有理由不能自己定义它们。

      这是一个折叠的例子:

      let foldi (folder: int -> int -> 'S -> 'T -> 'S) (state: 'S) (array: 'T[,]) =
          seq {
              for x in 0 .. Array2D.length1 array - 1 do
                  for y in 0 .. Array2D.length2 array - 1 do
                      yield (x, y, array.[x, y])
          }
          |> Seq.fold (fun acc (x, y, e) -> folder x y acc e) state
      

      如需常规折叠和更深入的解释,请查看here

      【讨论】:

        【解决方案3】:

        如果我需要使用折叠函数,我通常使用 Seq.cast,但这仅适用于 fold(不适用于 foldi)。

        我正在添加这个解决方案,如果需要,例如,扫描:

        let array2dFold folder (state:'State) (source:'T[,]) =
              source
              |>   ( Seq.cast<'T> >> Seq.fold folder state ) 
        

        由于它不依赖于变异,它很可能比以前的解决方案慢。

        【讨论】:

          猜你喜欢
          • 2016-04-04
          • 2011-01-24
          • 1970-01-01
          • 2013-10-30
          • 1970-01-01
          • 1970-01-01
          • 2010-11-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多