F#Seq.sortBy按降序排列

Mar*_*arl 22 f#

我对F#很新,并且来自Seq.sortBy函数但是它按升序排序我的列表.如何使用Seq.sort按降序排序?

例如,一个示例代码将是......

let DisplayList =
seq{0..10}
|> Seq.sortBy(fun x -> x)
|> Seq.iter(fun x -> Console.WriteLine(x.ToString()))
Run Code Online (Sandbox Code Playgroud)

给我一个输出1 2 3 4 5 6 7 8 9 10,当我真的希望它从10到1.

Bri*_*ian 21

看其他答案,要注意一元减号和MININT:

let a = [| 1; -1; System.Int32.MinValue; 0; System.Int32.MaxValue; 1 |]

printfn "%A" (a |> Array.sortBy (fun x -> x))
// [|-2147483648; -1; 0; 1; 1; 2147483647|]

printfn "%A" (a |> Array.sortBy (fun x -> -x))  // uh-oh!
// [|-2147483648; 2147483647; 1; 1; 0; -1|]
Run Code Online (Sandbox Code Playgroud)

我想你实际上想要负x-minus-one:

printfn "%A" (a |> Array.sortBy (fun x -> -x - 1))
// [|2147483647; 1; 1; 0; -1; -2147483648|]
Run Code Online (Sandbox Code Playgroud)

对于跨越的环绕整数类型-2^N..2^N-1.

  • 布赖恩,我希望你不介意,但我添加了评论显示输出. (2认同)
  • 就像旁注`-x-1 = ~~~ x`一样,因为`-x = ~~~ x + 1`。请参阅[二进制补码](https://en.wikipedia.org/wiki/Two%27s_complement)。因此,您可以根据需要将((fun x-> -x-1))缩短为简单的((~~~))。 (2认同)

Pat*_*ald 21

F#4.0(Visual Studio 2015)介绍Seq.sortByDescendingSeq.sortDescending

let DisplayList =
    seq { 0..10 }
    |> Seq.sortDescending         ' or |> Seq.sortByDescending id
    |> Seq.iter Console.WriteLine
Run Code Online (Sandbox Code Playgroud)

请参阅https://github.com/Microsoft/visualfsharp/wiki/F%23-4.0-Statushttps://github.com/fsharp/FSharpLangDesign/blob/master/FSharp-4.0/ListSeqArrayAdditions.md


Mau*_*Mau 20

更短:

seq { 0..10 } 
    |> Seq.sortBy (~-)    // Unary minus
    |> Seq.iter (printfn "%d")
Run Code Online (Sandbox Code Playgroud)


Ste*_*sen 18

首先,让我们Seq使用与sortWithList和Array相同的函数进行扩展.

namespace Microsoft.FSharp.Collections
module Seq =
    let sortWith f e = 
        let e' = e |> Seq.toArray
        e' |> Array.sortInPlaceWith f
        e' |> Seq.readonly
Run Code Online (Sandbox Code Playgroud)

接下来,让我们扩展Operators一个经常有用的flip功能.

namespace Microsoft.FSharp.Core
module Operators =
    let flip f x y = f y x
Run Code Online (Sandbox Code Playgroud)

现在,我们可以利用通用的通用compare函数(您可以将其与任何可比元素序列一起使用)和安全(关于Brian的观察)反向序列排序.

{0..10}
|> Seq.sortWith (flip compare)
|> Seq.iter (printfn "%A")
Run Code Online (Sandbox Code Playgroud)


dah*_*byk 9

另一种选择是包装System.Linq.Enumerable.OrderByDescending():

// #r "System.Core"
module Seq =
    let sortByDesc f s = Enumerable.OrderByDescending(s, new Func<'a, 'b>(f))

{0..10} |> Seq.sortByDesc (fun x -> x)
Run Code Online (Sandbox Code Playgroud)


Jar*_*Par 7

您可以通过提供否定键来解决此问题

let DisplayList = 
  seq { 0..10 } 
  |> Seq.sortBy (fun x -> -x)
  |> Seq.iter (fun x -> Console.WriteLine(x.ToString()))
Run Code Online (Sandbox Code Playgroud)

使用printf函数在F#中显示文本也更容易(并且类型更安全).例如

let DisplayList = 
  seq { 0..10 } 
  |> Seq.sortBy (fun x -> -x)
  |> Seq.iter (printfn "%d")
Run Code Online (Sandbox Code Playgroud)


pbl*_*cci 6

如果你提前知道你会有一个相对较小的序列,我认为这更具可读性......

let x = seq { 0.. 10 } |> Seq.toArray |> Array.rev

当然,如果你有一个可能非常大的序列,它是不可取的.


小智 5

:使用一元减解决方案(fun x -> -x - 1),并(fun x -> -x)当你无符号类型不工作:

let a = [| 0uy; 255uy; 254uy; 1uy |]
printfn "%A" (a |> Array.sortBy (fun x -> -x - 1))
// error FS0001: The type 'byte' does not support the operator '~-'
Run Code Online (Sandbox Code Playgroud)

相反,我们可以使用-x = ~~~x + 1where ~~~是一个按位否定运算符的事实-x - 1 = ~~~x.因此,适用于有符号和无符号类型的简短解决方案:

Array.sortBy (~~~) // equivalent to Array.sortBy (fun x -> ~~~x)
Run Code Online (Sandbox Code Playgroud)

例子:

let a = [| 0uy; 255uy; 254uy; 1uy |]
printfn "%A" (a |> Array.sortBy (~~~))
// [|255uy; 254uy; 1uy; 0uy|]
let a = [| 1; -1; System.Int32.MinValue; 0; System.Int32.MaxValue; 1 |]
printfn "%A" (a |> Array.sortBy (~~~))
// [|2147483647; 1; 1; 0; -1; -2147483648|]
Run Code Online (Sandbox Code Playgroud)