F # Seq.sortBy в порядке убывания - PullRequest
22 голосов
/ 24 июня 2010

Я довольно новичок в F # и пришел с функцией Seq.sortBy, однако она сортирует мой список в порядке возрастания.Как заставить его сортировать в порядке убывания, используя Seq.sort?

Например, пример кода будет ...

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

дает мне вывод 1 2 3 45 6 7 8 9 10, когда я действительно хочу это сделать с 10 до 1.

Ответы [ 8 ]

21 голосов
/ 02 декабря 2014

F # 4.0 (Visual Studio 2015) представлен Seq.sortByDescending и Seq.sortDescending

let DisplayList =
    seq { 0..10 }
    |> Seq.sortDescending         ' or |> Seq.sortByDescending id
    |> Seq.iter Console.WriteLine

См. https://github.com/Microsoft/visualfsharp/wiki/F%23-4.0-Status и https://github.com/fsharp/FSharpLangDesign/blob/master/FSharp-4.0/ListSeqArrayAdditions.md

21 голосов
/ 24 июня 2010

Глядя на другие ответы, остерегайтесь унарного минуса и 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|]

Я думаю, что вы на самом деле хотите, чтобы отрицательный-x-минус один:

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

для целого числа с переносомтип, охватывающий -2^N..2^N-1.

20 голосов
/ 24 июня 2010

Еще короче:

seq { 0..10 } 
    |> Seq.sortBy (~-)    // Unary minus
    |> Seq.iter (printfn "%d")
17 голосов
/ 25 июня 2010

Во-первых, давайте расширим Seq с помощью функции sortWith, такой же, как у List и Array.

namespace Microsoft.FSharp.Collections
module Seq =
    let sortWith f e = 
        let e' = e |> Seq.toArray
        e' |> Array.sortInPlaceWith f
        e' |> Seq.readonly

Далее, давайте расширим Operators с помощью часто полезной flip функции.

namespace Microsoft.FSharp.Core
module Operators =
    let flip f x y = f y x

Теперь мы можем использовать универсальную функцию compare для универсального (вы можете использовать это с любой последовательностью сопоставимых элементов) и безопасной (в отношении наблюдения Брайана) обратной последовательности.

{0..10}
|> Seq.sortWith (flip compare)
|> Seq.iter (printfn "%A")
9 голосов
/ 25 июня 2010

Другой вариант - обернуть 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)
7 голосов
/ 24 июня 2010

Вы можете исправить это, указав отрицательный ключ

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

Также немного проще (и введите безопаснее) использовать функции printf для отображения текста в F #.Например

let DisplayList = 
  seq { 0..10 } 
  |> Seq.sortBy (fun x -> -x)
  |> Seq.iter (printfn "%d")
6 голосов
/ 24 июня 2010

Если вы заранее знаете, что у вас будет относительно небольшая последовательность, я думаю, что это более читабельно ...

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

Конечно, это не такрекомендуется, если вы получили потенциально очень большую последовательность.

5 голосов
/ 26 июля 2013

Решения, использующие унарный минус: (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 '~-'

Вместо этого мы можем использовать тот факт, что -x = ~~~x + 1, где ~~~ - оператор побитового отрицания и, следовательно, -x - 1 = ~~~x. Итак, короткое решение, которое работает как со знаком, так и без знака:

Array.sortBy (~~~) // equivalent to Array.sortBy (fun x -> ~~~x)

Примеры:

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|]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...