2012-03-29 33 views
1

蔭的F#的新手,我有以下的出發點:F#發現與同一ID記錄的記錄名單,並加入了他們的價值觀

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] 

此列表現在變得很長,在這份名單中,我現在需要先確定所有的AB公司具有相同的ID,那麼我想淨明他們的幻燈片,使一個新的列表導致

let bunchedABReduced = [aB1; aB2New],其中

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

我正在通過msdn上的F#庫閱讀,但到目前爲止我還不知道如何解決這個問題,對於代碼命題會很高興。

非常感謝 馬丁

+0

aB的幻燈片中總是有3個元組嗎?或者這個列表可以有任何長度? – gjvdkamp 2012-03-29 12:26:00

+1

定義「淨出他們的幻燈片」?我無法從你的問題中找出你正在應用的操作。 – 2012-03-29 12:26:08

+0

@Onorio:操作加起來的值 – Eva 2012-03-29 12:41:05

回答

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 

享受!

+0

好的方法@gjvdkamp。我總是試圖在一步一步地解決問題的時候,如果按照您這樣做的方式進行分段處理,他們的工作會更好。 – 2012-03-29 13:13:48

+0

@gjvdkamp非常感謝,等待最後一點;-),當你開始理解時,它並不是那麼直接地進入F#思維的方式,但非常酷。 – Eva 2012-03-29 13:28:39

+0

好的!儘管如此,請謹慎使用Seq.groupBy,因爲它需要在整個序列繼續前重複遍歷整個序列,因此它可能會耗用大量的內存用於大型序列。在這種情況下,您想要使用摺疊並沿原始列表踩下字典。 – gjvdkamp 2012-03-29 13:45:58

0

試試這個:

建立一個字典,其中鍵將你遇到的ID和值將是一個「網狀」 AB型爲ID。

然後使用字典作爲您的狀態在列表上運行摺疊*,並讓您在整個列表中摺疊的功能通過ID在字典中累積條目(在您去的時候「淨化」它們)。

之後,您可以將所有字典的值放入返回列表中。

如果你不能「淨」他們,那麼你可以存儲一個項目列表作爲值而不是一個單一的「網狀」值,然後在摺疊完成後進行淨值計算。

*倍http://msdn.microsoft.com/en-us/library/ee353894.aspx

編輯:提出了一些事情更清晰

相關問題