简体   繁体   中英

F# sorting array

I have an array like this,

[|{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;};
  .......
    |]

How do I sort this array according to "turnover"? Thanks (does not have much context to explain the code section? how much context should I write)

假设数组在arr您可以执行以下操作

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

I know this has already been answered beautifully; however, I am finding that, like Haskell, F# matches the way I think and thought I'd add this for other novices :)

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

Note 1: "a >> b" is function composition and means "create a function, f, such that fx = b(a(x))" as in "apply a then apply b" and so on if it continues: a >> b >> c >>...

Note 2: "@" is list concatenation, as in [1..100] = [1..12] @ [13..50] @ [51..89] @ [90..100]. This is more powerful but less efficient than cons, "::", which can only add one element at a time and only to the head of a list, a::[b;c;d] = [a;b;c;d]

Note 3: the List.filter (fun e ->...) expressions produces a "curried function" version holding the provided filtering lambda.

Note 4: I could have made "smaller" and "larger" lists instead of functions (as in "xs |> filter |> sort"). My choice to make them functions was arbitrary.

Note 5: The type signature of the sortData function states that it requires and returns a list whose elements support comparison:

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

Note 6: There is clarity in brevity (despite this particular post :) )

As a testament to the algorithmic clarity of functional languages, the following optimization of the above filter sort is three times faster (as reported by VS Test Explorer). In this case, the list is traversed only once per pivot (the first element) to produce the sub-lists of smaller and larger items. Also, an equivalence list is introduced which collects matching elements away from further comparisons.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM