我是F#新手,我有以下起点:
type aB = { ID: int; Slide: list<string * int> }
// examples of aB's
let aB1 = { ID = 1; Slide = [("-10%",-20); ("0%",0); ("10%",20)] }
let aB2 = { ID = 2; Slide = [("-10%",6); ("0%",0); ("10%",3)] }
let correctoraB2 = {ID = 2; Slide = [("-10%", -2); ("0%", 0); ("10%", -1)] }
// Now we bunch the aB`s in a list together
let bunchedABRaw = [aB1; aB2; correctoraB2]
此列表现在可以变得很长,在此列表中,我现在需要首先识别具有相同ID的所有aB,然后我想将其幻灯片网络化,以便生成新列表
let bunchedABReduced = [aB1; aB2New]
,其中
aB2New = { ID = 2; Slide = [("-10%",4); ("0%",0); ("10%",2)] }
我正在阅读msdn上的F#库,但到目前为止我还不知道如何解决这个问题,对于代码命题会非常高兴。
非常感谢 马丁
答案 0 :(得分:2)
当我有一分钟的时候,我可以通过这个工作。
这是您可以合并两个aB的幻灯片的第一部分:
// this function can merge two slides
let mergeSlides l1 l2 =
List.zip l1 l2
|> List.map (fun ((a1, b1), (a2,b2)) -> (a1, b1+b2))
// see what it does
mergeSlides aB2.Slide correctoraB2.Slide
这个位将所有aB分组为相同的Id:
let grp = bunchedABRaw
|> Seq.groupBy (fun a -> a.ID)
现在我们可以使用mergeSlides作为折叠函数,我们使用具有相同Id的Ab的每个序列折叠来制作网状aB。
所以这就是整个事情:
let mergeSlides l1 l2 =
List.zip l1 l2
|> List.map (fun ((a1, b1), (a2,b2)) -> (a1, b1+b2))
let net =
bunchedABRaw
|> Seq.groupBy (fun a -> a.ID)
|> Seq.map (fun (i, s) -> (i, s |> Seq.map (fun a -> a.Slide))) // strip away the slides
|> Seq.map (fun (i, s) -> (i, List.ofSeq s)) // turn seq<slide> into list<slide>
|> Seq.map (fun (i, l) -> (i, List.fold mergeSlides l.Head l.Tail)) // so we can use HEad and Tail
|> Seq.map (fun (i, l) -> {ID=i;Slide=l}) // and Project into aB
|> List.ofSeq // and then List
享受!
答案 1 :(得分:0)
试试这个:
设置一个字典,其中的键将是您遇到的ID,值将是该ID的“网状”aB类型。
然后使用字典作为您的状态在列表上运行折叠*并使您在列表中折叠的功能按ID累积字典中的项目(随时“净化”它们)。
之后,您可以将所有字典的值放入返回列表中。
如果您不能随意“净化”它们,那么您可以将项目列表存储为值而不是单个“净额”值,然后在折叠结束后进行净额结算。
* fold http://msdn.microsoft.com/en-us/library/ee353894.aspx
编辑:让事情更清楚