F# - 减少多个阵列的功能

时间:2017-12-15 08:25:53

标签: arrays f# reduce

我正在尝试实现以下迭代的步骤序列,但成效有限:

   (*
      Foreach element in fifth do
      sum elements in second filtered by matching characters in first and
      subtract elements in fourth filtered by matching characters in third

      // For Example: [|"ABC"|] -> 44.0 = (13.0 + 17.0 + 19.0) - (2.0 + 3.0)
      // For Example: [|"ABD"|] -> 46.0 = (13.0 + 17.0 + 23.0) - (2.0 + 5.0)
      // For Example: [|"ABE"|] -> 51.0 = (13.0 + 17.0 + 29.0) - (3.0 + 5.0)
      // For Example: [|"ACD"|] -> 46.0 = (13.0 + 19.0 + 23.0) - (2.0 + 7.0)
      // For Example: [|"ACE"|] -> 51.0 = (13.0 + 19.0 + 29.0) - (3.0 + 7.0)
      // For Example: [|"ADE"|] -> 53.0 = (13.0 + 23.0 + 29.0) - (5.0 + 7.0)
      // For Example: [|"BCD"|] -> 46.0 = (17.0 + 19.0 + 23.0) - (2.0 + 11.0)
      // For Example: [|"BCE"|] -> 51.0 = (17.0 + 19.0 + 29.0) - (3.0 + 11.0)
      // For Example: [|"BDE"|] -> 53.0 = (17.0 + 23.0 + 29.0) - (5.0 + 11.0)
      // For Example: [|"CDE"|] -> 53.0 = (19.0 + 23.0 + 29.0) - (7.0 + 11.0)
   *)

这是@ xuanduc987最近帮助我解决问题的一个更复杂的版本。

module SOQN =

   open System

   let first  = [|"A"; "B"; "C"; "D"; "E"; "F"; "G"; "H"; "I"; "J"|]
   let second = [|13.0; 17.0; 19.0; 23.0; 29.0; 0.0; 0.0; 0.0; 0.0; 0.0|]
   let third  = [|"ABCD"; "ABCE"; "ABDE"; "ACDE"; "BCDE"|]
   let fourth = [|2.0; 3.0; 5.0; 7.0; 11.0|]
   let fifth  = [|"ABC"; "ABD"; "ABE"; "ACD"; "ACE"; "ADE"; "BCD"; "BCE"; "BDE"; "CDE"|]

   let sixth = 
      [[for i in [0..fifth.Length - 1] do
         yield (sumFunc second first fifth.[i] - 
                subtractFunc third fourth fifth.[i])]]


   // Expected Result:  Sixth:  [| 44.0; 46.0; 51.0; 46.0; 51.0; 53.0; 46.0; 51.0; 53.0; 53.0 |]

1 个答案:

答案 0 :(得分:1)

这个怎么样?

let sixth = 
    Array.init fifth.Length (fun i ->        
        let f a b (g:string->bool) =
            Seq.zip a b 
            |> Seq.filter (fun (e,_) -> g e)
            |> Seq.map snd
            |> Seq.sum
        let x = f first second (fun e -> fifth.[i].Contains(e))
        let y = f third fourth (fun e -> Seq.forall (fun x -> e.Contains(x)) (Seq.map string fifth.[i]))
        x - y)

它给了我:

[|44.0; 46.0; 51.0; 46.0; 51.0; 53.0; 46.0; 51.0; 53.0; 53.0|]

你说

  

通过匹配第三个

中的字符进行过滤

但我认为它应该通过匹配第三个字符来过滤,否则我没有得到你描述的44个。