我有三个数组 - 第一个是一个浮点数组,第二个是一个字符串数组,而第三个是一个包含已排序的浮点数组,来自第一个数组的唯一值。
module SOQN =
open System
type collective = { score:double; yes:int; no:int; correct:double }
let first = [| 25; 20; 23; 10; 8; 5; 4; 12; 19; 15; 15; 12; 11; 11 |]
let second = [| "No"; "No"; "Yes"; "Yes"; "Yes"; "No"; "Yes"; "No"; "Yes"; "Yes"; "Yes"; "No"; "Yes"; "No" |]
let third = Array.distinct (first |> Array.sort)
let fourth = Seq.zip first second
let fifth = fourth |> Seq.sortBy fst
let yesCounts =
fifth
|> Seq.filter (fun (_, y) -> if y = "Yes" then true else false)
|> Seq.map fst
let noCounts =
fifth
|> Seq.filter (fun (_, y) -> if y = "No" then true else false)
|> Seq.map fst
(*
Expected Result:
third = [| 4; 5; 8; 10; 11; 12; 15; 19; 20; 23; 25 |]
yesCounts = [| 1; 1; 2; 3; 4; 4; 6; 7; 7; 8; 8 |]
noCounts = [| 0; 1; 1; 1; 2; 4; 4; 4; 5; 5; 6 |]
yesProportions = [| 1/1; 1/2; ;2/3 3/4; 4/6; 4/8; 6/10; 7/11; 7/12; 8/13; 8/14 |]
*)
我需要通过迭代第三个数组生成一个新的集合,其中包括是和没有计数" &LT = "它的每个价值观。最后,我需要遍历这个新集合,以创建一个新列,其中包含每个值的是比例,并打印每个唯一值及其匹配的是比例。
请指教?
答案 0 :(得分:6)
首先,使用一些更有意义的名称:
let nums = [| 25; 20; 23; 10; 8; 5; 4; 12; 19; 15; 15; 12; 11; 11 |]
let yesNos = // convert string -> bool to simplify following code
[| "No"; "No"; "Yes"; "Yes"; "Yes"; "No"; "Yes"; "No"; "Yes"; "Yes"; "Yes"; "No"; "Yes"; "No" |]
|> Array.map (fun s -> s = "Yes")
let distinctNums = nums |> Array.distinct |> Array.sort
let numYesNos = Array.zip nums yesNos
然后,如果你真的想要为每个是/否/比率计算单独收集,你可以使用折叠构建那些:
let foldYesNos num (yesCounts, noCounts, yesRatios) =
// filter yes/no array by <= comparison
// then partition it into two arrays by the second bool item
let (yays, nays) = numYesNos |> Array.filter (fun (n,_) -> n <= num) |> Array.partition snd
let yesCount = Array.length yays
let noCount = Array.length nays
let yesRatio = float yesCount / float(yesCount + noCount)
(yesCount::yesCounts, noCount::noCounts, yesRatio::yesRatios)
// fold *back* over the distinct numbers
// to make the list accumulation easier/not require a reversal
let (yays, nays, ratio) = Seq.foldBack foldYesNos (distinctNums |> Seq.sort) ([], [], [])
但是,我假设您在样本中发布了Collective
记录类型,您可能实际上想要为每个输入发出以下记录之一:
type Collective = { score:int; yes:int; no:int; correct:float }
let scoreNum num =
let (yays, nays) = numYesNos |> Array.filter (fun (n,_) -> n <= num) |> Array.partition snd
let yesCount = Array.length yays
let noCount = Array.length nays
let yesRatio = float yesCount / float(yesCount + noCount)
{ score = num; yes = yesCount; no = noCount; correct = yesRatio }
distinctNums |> Array.map scoreNum
您可以看到此代码非常相似,它只返回每个输入的Collective
记录,而不是为单个计算构建列表,因此我们可以使用 map 而不是a fold 。