生成多维数组的子集

时间:2015-03-11 17:17:18

标签: multidimensional-array f#

我通过将我现有的一个.NET类转换为F#来玩F#类。该类使用8列的2维数组和0到10行的0-1024整数数据

我的getPar方法返回一列数据。我的gatePar采用lo和hi谓词并返回2元组的布尔值和索引。元组告诉我任何给定的索引是否属于lo和hi值。

使用gatePar元组在基于单个列的限制内返回整个真值或值的最佳方法是什么?

我希望生成一个包含8列和10000行或更少行的dataArray子集。

我的代码:

let mutable lo = int16(300)
let mutable hi = int16(700)

member x.SetLow low = lo <- int16(low)
member x.SetHigh high = hi <- int16(high)

member x.Par =
    x.dataArray.[0..0,0..] 

member x.flatten (dataArray:'a[,]) = dataArray |> Seq.cast<'a>

member x.getRow r (dataArray:_[,]) =
    x.flatten dataArray.[*,r..r] |> Seq.toArray  

member x.getColumn c (dataArray:_[,]) =
    x.flatten dataArray.[*,c..c] |> Seq.toArray

member x.getPar c  =
    x.flatten x.dataArray.[c..c,*] |> Seq.toArray

member x.gatePar c =
    x.flatten x.dataArray.[c..c,*] 
    |> Seq.mapi (fun i x -> x > lo && x < hi, i)
    |> Seq.toArray

从VB.NET调用它:

inst.SetLow(200)
inst.SetHigh(500)
Dim results = inst.gatePar(2)

1 个答案:

答案 0 :(得分:1)

我认为这是你正在寻找的东西。将它作为一个模块,因为它更适合,你可以继续为你的课程进行调整。

module ArrayFilter =
    /// Converts a jagged array to a multidimensional one.
    /// (if you need to).
    let fromJagged dim1 dim2 (arr: 'a[][]) =
        Array2D.init dim1 dim2 (fun x y -> arr.[x].[y])

    /// Pick only the rows that match the indices.
    let pickRows indices (dataArray:'a[,]) =
        [| for idx in indices do
               yield dataArray.[idx, *]    
            |]                
        |> fromJagged (Array.length indices) (Array2D.length2 dataArray)

    /// the first line is your gatePar, 
    /// the second converts the tuples into indices array.
    let filterIndices lo hi (arr: 'a[]) =
        Array.mapi (fun i x -> x > lo && x < hi, i) arr 
        |> Array.choose (fun (keep, idx) ->
            if keep then Some idx else None)  

    let filterOnColumn c lo hi (dataArray:'a[,]) =
        let indices =
            dataArray.[*, c]
            |> filterIndices lo hi

        pickRows indices dataArray

这不会因为效率而赢得任何奖项,但似乎很简单易懂。