2013-01-07 80 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)