Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List F#在记录列表中查找具有相同id的记录,并将其值相加_List_F#_Find - Fatal编程技术网

List F#在记录列表中查找具有相同id的记录,并将其值相加

List F#在记录列表中查找具有相同id的记录,并将其值相加,list,f#,find,List,F#,Find,我是个新手,我有以下出发点: 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;

我是个新手,我有以下出发点:

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]
type aB={ID:int;幻灯片:列表}
//aB的例子
设aB1={ID=1;Slide=[(“-10%”,-20);(“0%”,0);(“10%”,20)]]
设aB2={ID=2;Slide=[(“-10%”,6);((-0%”,0);(-10%”,3)]]
设correctoraB2={ID=2;Slide=[(“-10%”,-2);(“0%”,0);(“10%”,-1)]]
//现在我们把aB排在一起
设bunchedABRaw=[aB1;aB2;correctoraB2]
这个列表现在可能会变得很长,在这个列表中,我需要首先确定所有具有相同ID的aB,然后我想将它们的幻灯片整理出来,以便生成一个新的列表

让bunchedABReduced=[aB1;aB2New]
,其中

aB2New={ID=2;Slide=[(“-10%”,4);(“0%”,0);(“10%”,2)]}

我正在阅读msdn上的F#库,但到目前为止我还不知道如何解决这个问题,我非常乐意接受代码建议

非常感谢 马丁

试试这个:

设置一个字典,其中键将是您遇到的ID,值将是该ID的“netted”aB类型

然后使用字典作为您的状态在列表上运行fold*,并使您在列表中折叠的功能按ID累积字典中的项目(“在运行时对其进行净额结算”)

之后,您可以将字典的所有值放入一个返回列表中

如果您不能在进行时将其“净额结算”,那么您可以将项目列表存储为值,而不是单个“净额结算”值,然后在折叠完成后进行净额结算

*折叠


编辑:让一些事情变得更清楚

好的,等我有时间的时候再处理一下

这里是第一部分,您可以合并两个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
此位将具有相同Id的所有aB分组:

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
让合并幻灯片l1 l2=
List.zip l1 l2
|>List.map(乐趣((a1,b1)、(a2,b2))->(a1,b1+b2))
撒网=
班切达布
|>Seq.groupBy(趣味a->a.ID)
|>Seq.map(fun(i,s)->(i,s |>Seq.map(fun a->a.Slide))//去掉幻灯片
|>Seq.map(fun(i,s)->(i,List.ofSeq s))//将Seq转换为List
|>Seq.map(fun(i,l)->(i,List.fold,l.Head,l.Tail))//所以我们可以使用Head和Tail
|>Seq.map(fun(i,l)->{ID=i;Slide=l})//并投影到aB中
|>List.ofSeq//然后List

享受吧

aB的幻灯片中总是有3个元组吗?或者这个列表可以是任意长度的?定义“将他们的幻灯片过滤掉”?我无法从你的问题中看出你正在应用哪个操作。@Onorio:该操作正在将values@gjvdkamp:可以有任意数量的tuplesGood approach@gjvdkamp。我总是试着一步一个脚印地解决问题,如果按照你这样做的方式分段处理,效果会更好。@gjvdkamp非常感谢,非常可以理解,等待最后一点;-),进入F#思考的方式并不是那么简单,但是当你开始理解的时候,你会觉得很酷。好的,完成了!但是要小心使用Seq.groupBy,因为它需要在整个序列上迭代才能继续,因此它可能会为大序列占用大量内存。在这种情况下,您需要使用折叠和踩踏字典沿原始列表。