在F#中将obj [,]类型的2D数组转换为元组序列?

时间:2014-07-27 19:43:17

标签: arrays f# tuples sequence

在学习F#时,我被另一个库给出了一个obj [,](一个2D对象数组)。该数组有两列,第一列是long,第二列是double。

我需要将它转换为一系列元组,其中第一个是System.DateTime,我通过使用DateTime.FromOADate转换long来获得,第二列保持不变,作为元组的第二个。

let arrayOfArrays:obj[][] = [| [| 41847; 0.02 |]; [|41877; 0.05 |] |]
let twoDimensionalArray = Array2D.init 2 2 (fun i j -> arrayOfArrays.[i].[j]) 

在这个例子中,我需要将twoDimensinalArray更改为一系列元组,第一个元素是一个元组,日期时间为27-Jul-14,双精度为0.02。该序列的第二个元素将包含26-Aug-14和双0.05。

此外,我需要执行一些检查,因此我需要能够插入一个函数来检查每一行作为参数(验证器)。

编辑: 我只收到twoDimensionalArray,我没有arrayOfArrays(它只在代码示例中生成了twoDimensionalArray)。

我试图修改代码以循环遍历行但是函数convertArray似乎没有在seq上循环,这是我尝试过的(事实上第一列也是双重的)

let validate (x, y) =
    true
// ... your validation code ...

let convertArray(validate,a:obj[,]) =
    let dateOfInt x = System.DateTime.FromOADate(x)
    // ... convert integer to DateTime
    seq { for rowidx in 0 .. a.GetLength(0) - 1 do
            let row = a.[rowidx, 0 .. (a.GetLength(1)-1)]
            match row with
            // note the use of type test pattern -
            // we need to check the types of row elements
            | [| :? double as x; :? double as y |] ->
                let t = (dateOfInt (float x), y)
                yield
                    if validate t then Some t
                    else None
            | other -> failwithf "Invalid row: %A" other
    }
let arrayOfArrays:obj[][] = [| [| 41847.0; 0.02 |]; [|41877.0; 0.05 |] |]
let twoDimensionalArray = Array2D.init 2 2 (fun i j -> arrayOfArrays.[i].[j]) 
let points = convertArray(validate,twoDimensionalArray)
printfn "%A" (Seq.toList points);;

1 个答案:

答案 0 :(得分:1)

假设您想要获得(DateTime * double) option的序列,意味着Some x用于验证通过,None用于验证失败:

let validate (x, y) =
    // ... your validation code ...

let convertArray validate a =
    let dateOfInt x =
        // ... convert integer to DateTime

    seq {
        for row in a do
            match row with
            // note the use of type test pattern -
            // we need to check the types of row elements
            | [| :? int as x; :? double as y |] ->
                let t = (dateOfInt x, y)
                yield
                    if validate t then Some t
                    else None
            | other -> failwithf "Invalid row: %A" other
    }

let twoDimensionalArray = convertArray validate arrayOfArrays

当验证失败时,您还可以重做此操作以引发异常。