繁体   English   中英

F#-数组-减去N-1元素

[英]F# - Array - Subtract N-1 Element

我正在尝试使用常量和两个数组减去n-1元素作为计算的一部分,如下所示:

module SOQN =

   open System

   let firstArray  = [|0.02;0.03;0.05;0.07;0.11|]
   let secondArray = [|0.30;0.50;0.70;1.10;1.30|]
   let constant    = 0.37

   let minusOneElement = 0.00
   let result = Array.map2 (fun x y -> (x - (constant * (y - minusOneElement)))) firstArray secondArray

   printfn "Result: %A" result

   (*
      Expected Result: [|-0.091;-0.044;-0.024;0;0|]
      Actual Result:   [|-0.091;-0.155;-0.209;-0.337;-0.371|]
   *)

如您所见,第一个输出值是正确的,但其余的并没有给出我不知道如何构造“ minusOneElement”的信息,它应该是“ secondArray”的连续元素-即0.30 0.50 0.70和1.10。 还有一个额外的限制,即“ secondArray”的当前元素小于一个。 否则,将相应的结果值设置为零。

如果我正确地解释了您的要求,则希望采用第二个数组并生成对(当前元素,前一个元素),其中第一个当前元素的前一个元素设置为0.0。

您可以使用Seq.windowed生成对(在为第一个上一个元素添加单例数组0.0之前):

let fst  = [|0.02;0.03;0.05;0.07;0.11|]
let snd = [|0.30;0.50;0.70;1.10;1.30|]
let snd' = Seq.windowed 2 (Array.append [|0.0|] snd) |> Seq.toArray
let constant = 0.37

修改地图操作:

let result = Array.map2 (fun x (y: float []) -> (if y.[1] < 1.00 then (x - (constant * (y.[1] - y.[0]))) else 0.00)) fst snd'

产生预期的结果(请注意snd对):

val snd' : float [] [] =
    [|[|0.0; 0.3|]; [|0.3; 0.5|]; [|0.5; 0.7|]; [|0.7; 1.1|]; [|1.1; 1.3|]|]

val result : float [] = [|-0.091; -0.044; -0.024; 0.0; 0.0|]

以下代码段似乎有效:

module SOANS =

   open System

   let firstArray  = [|0.02;0.03;0.05;0.07;0.11|]
   let secondArray = [|0.30;0.50;0.70;1.10;1.30|]
   let lenSecondArray = secondArray.Length
   let thirdArray = Array.permute (fun index -> (index + (1)) % lenSecondArray) secondArray
   thirdArray.[0] <- 0.00
   let constant    = 0.37

   let result = Array.map3 (fun x y z -> (if y < 1.00 then (x - (constant * (y - z))) else 0.00)) firstArray secondArray thirdArray

   printfn "Result: %A" result

   (*
      Expected Result: [|-0.091;-0.044;-0.024;0;0|]
      Actual Result:   [|-0.091;-0.044;-0.024;0;0|]
   *)

如果可能的话,我希望能有一个更惯用的解决方案。

对于每个y.[n] ,构造一个元组及其与y.[n-1] 为此目的的一种有效方法是scan操作,该操作用fold的中间结果填充集合。 Seq.windowed (或就此而言, Seq.pairwise )相比,所得集合的长度不少于源。 它包含一个额外的元素,初始状态为前置。

let first = [|0.02;0.03;0.05;0.07;0.11|]
let second = [|0.30;0.50;0.70;1.10;1.30|]

let diff2 = Array.scan (fun (prv, _) cur -> cur, cur - prv) (0., 0.) second

(first, diff2.[1..])
||> Array.map2 (fun x (y, dy) ->
    if y < 1. then x - 0.37 * dy else 0. )
// val it : float [] = [|-0.091; -0.044; -0.024; 0.0; 0.0|]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM