将每2个元素映射到函数/构造函数

时间:2015-11-06 17:10:05

标签: f#

我有一个整数数组,我想在其中将每两个元素发送到另一个函数的构造函数。

intArray |> Array.map (fun x, y -> new Point(x, y))

这样的东西

这可能吗?我是F#和函数式编程的新手,所以我试图避免循环遍历数组中的每两个项目并将该点添加到列表中。我希望这是合理的。

3 个答案:

答案 0 :(得分:4)

您可以使用Array.chunkBySize

intArray 
    |> Array.chunkBySize 2 
    |> Array.map (function 
        | [|x; y|] -> new Point (x, y) 
        | _ -> failwith "Array length is not even.")

答案 1 :(得分:4)

如果使用F#4.0,请使用Gustavo的方法。对于F#3,你可以这样做:

intArray
    |> Seq.pairwise // get sequence of tuples of element (1,2); (2,3); (3,4); (4,5) etc
    |> Seq.mapi (fun i xy -> i, xy) // combine the index with the tuple
    |> Seq.filter (fun (i,_) -> i % 2 = 0) // Filter for only the even indices to get (1,2); (3,4)
    |> Seq.map (fun xy -> Point xy) // make a point from the tuples
    |> Array.ofSeq // convert back to array

答案 2 :(得分:0)

现有答案的另一种解决方案是编写一个自定义函数,使用模式匹配创建一个列表/元组数组:

let chunkify arr =
    let rec chunkify acc lst =
        if (List.length lst) > 1 then (* proceed if there are at least two elements *)
            match lst with 
            (* save every constructed pair, until the input is not empty *)
            | h1 :: h2 :: tail -> chunkify ([(h1, h2)] @ acc) tail
            | _ -> acc (* else return the list of pairs *)
        else (* return the list of pairs *)
            acc

    chunkify List.empty (List.ofSeq arr) |> List.rev |> Array.ofSeq  

然后可以像这样使用该函数:

// helper
let print = (fun (x:'a, y:'a) -> printfn "new Object(%A,%A)" x y)
// ints
[|1;2;3;4;5;6|] 
|> chunkify 
|> Array.iter print
// strings
[|"a";"b";"c";"d";"e"|] 
|> chunkify 
|> Array.map print 
|> ignore

输出结果为:

new Object(1,2)
new Object(3,4)
new Object(5,6)
new Object("a","b")
new Object("c","d")

此解决方案/方法使用pattern matchinglists