2013-01-07 125 views
1

我有一個這樣的數組,F#排序陣列

[|{Name = "000016.SZ"; 
    turnover = 3191591006.0; 
    MV = 34462194.8;}; 
    {Name = "000019.SZ"; 
    turnover = 2316868899.0; 
    MV = 18438461.48;}; 
    {Name = "000020.SZ"; 
    turnover = 1268882399.0; 
    MV = 7392964.366;}; 
    ....... 
    |] 

如何根據「營業額」排序了這陣?由於 (沒有太多的上下文來解釋代碼段?我應該多少背景下寫)

回答

7

假設數組是arr你可以做

arr |> Array.sortBy (fun t -> t.turnover) 
+1

或者,'arr |> Array.sortBy(fun {turnover = t} - > t)'。 – ildjarn

1

我知道這已回答精美的;然而,我發現,像Haskell中,F#我的思維方式相匹配,以爲我想補充這對於其他新手:)

let rec sortData = 
    function 
    | [] -> [] 
    | x :: xs -> 
    let smaller = List.filter (fun e -> e <= x) >> sortData 
    let larger = List.filter (fun e -> e > x) >> sortData 
    smaller xs @ [ x ] @ larger xs 

注1:「A >> B」爲功能成分和手段「創建函數f,使得fx = b(a(x))「,如在」應用a然後應用b「中,如果繼續:a >> b >> c >> ...

注2:「@」是列表級聯,如[1..100] = [1..12] @ [13..50] @ [51..89] @ [90..100]。這比cons更強大但效率更低,「::」,它只能一次添加一個元素,並且只能添加到列表的頭部,a :: [b; c; d] = [a; b; c ; d]

注意3:List.filter(fun e - > ...)表達式產生一個持有提供的過濾lambda的「curried函數」版本。注意4:我可以用「小」和「大」列表而不是函數(如「xs |> filter |> sort」)。我選擇讓它們起作用是任意的。

注5:sortData函數的類型簽名指出,它需要和返回的元素支持的比較列表:

_arg1:'a list -> 'a list when 'a : comparison 

注6:有清晰的簡潔(儘管這個特殊的職位:))

1

作爲函數式語言算法清晰度的一個證明,以上過濾器排序的優化速度比VS Test Explorer報告的快三倍。在這種情況下,每個數據透視表(第一個元素)僅被遍歷一次,以生成較小和較大項目的子列表。此外,還引入了一個等價列表,用於收集與進一步比較相匹配的元素。

let rec sort3 = 
    function 
    | [] -> [] 
    | x::xs -> 
     let accum tot y = 
     match tot with 
     | (a,b,c) when y < x -> (y::a,b,c) 
     | (a,b,c) when y = x -> (a,y::b,c) 
     | (a,b,c) -> (a,b,y::c) 
     let (a,b,c) = List.fold accum ([],[x],[]) xs 
     (sort3 a) @ b @ (sort3 c)