F# - 将函数应用于两个不同长度的数组

时间:2017-12-09 15:22:42

标签: arrays f#

我正在尝试将函数应用于两个不同长度的数组,但结果与我的预期不符。我需要重用第二个数组的元素(类似于R)来完成表达式:

module SOQN = 

open System

let first = [|2; 3; 5; 7; 11|]
let second = [|13; 17; 19|]

let result = 
    [for i in [0..first.Length-1] do
        for j in [0..second.Length-1] do
            yield (first.[i] * second.[j])]

printfn "Result: %A" result

// Actual Result: [|26; 34; 38; 39; 51; 57; 65; 85; 95; 91; 119; 133; 143; 187; 209|]
// Expected Result: [|26; 51; 95; 91; 187|]

我错过了什么?

2 个答案:

答案 0 :(得分:4)

我猜你在寻找像这样的东西

let result = 
    Array.mapi
        (fun i v -> second.[i % second.Length] * v) first

答案 1 :(得分:0)

以下是另一种方法:

let first = [|2; 3; 5; 7; 11|]
let second = [|13; 17; 19|]

let map2Cycle (x: 'T []) (y: 'T []) (f: 'T -> 'T -> 'S) =
    let lenx = Array.length x
    let leny = Array.length y

    let xInf = Seq.initInfinite (fun _ -> x) |> Seq.concat
    let yInf = Seq.initInfinite (fun _ -> y) |> Seq.concat

    Seq.map2 f xInf yInf
    |> Seq.take (max lenx leny)
    |> Array.ofSeq

map2Cycle first second (*)
// val it : int [] = [|26; 51; 95; 91; 187|]

这是一个稍微不同的一个:

let map2Cycle' (x: 'T []) (y: 'T []) (f: 'T -> 'T -> 'S) =
    let lenx = Array.length x
    let leny = Array.length y

    let (x', y') =
        if lenx >= leny then x |> Seq.ofArray, Seq.initInfinite (fun _ -> y) |> Seq.concat
        else Seq.initInfinite (fun _ -> x) |> Seq.concat, y |> Seq.ofArray

    Seq.map2 f x' y'
    |> Seq.take (max lenx leny)
    |> Array.ofSeq

map2Cycle' first second (*)
// val it : int [] = [|26; 51; 95; 91; 187|]