Как отсортировать переменную по возрастанию в F #? - PullRequest
0 голосов
/ 06 октября 2018

Как бы отсортировать список по переменной, но по возрастанию?

Что-то вроде:

Data |> List.sortBy(fun t -> t.Date,ascending(t.Value))

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

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

Вы можете легко сортировать по нескольким клавишам, по возрастанию, по убыванию или по любому другому сложному порядку, используя List.sortWith и степень композиции функций:

Все, что вам нужно, это пара вспомогательных функций и оператор:

let asc   f    a b = compare (f a) (f b)
let desc  f    a b = compare (f b) (f a)
let (&>) c1 c2 a b = match c1 a b with 0 -> c2 a b | r -> r

И asc, и desc получают функцию извлечения ключа типа 'T->'K и вызывают обобщенную функцию compare для сортировки в порядке возрастания или убывания.Оператор &> позволяет вам составлять их для сортировки по любому количеству клавиш.А так как вы также можете добавить свои собственные компараторы, с помощью этой техники возможна любая сортировка:

let ls = [ "dd"; "a"; "b"; "c"; "aa"; "bb"; "cc"]

ls |> List.sortWith(desc Seq.length &> 
                    asc  id)        
// result = ["aa"; "bb"; "cc"; "dd"; "a"; "b"; "c"]

ls |> List.sortWith( asc Seq.length &> 
                     desc id) 
// result = ["c"; "b"; "a"; "dd"; "cc"; "bb"; "aa"]

Ваш пример будет выглядеть так:

Data |> List.sortWith( desc (fun t -> t.Date)  &> 
                        asc (fun t -> t.Value))
0 голосов
/ 07 октября 2018

Исходя из вашего примера, похоже, что вы хотите использовать несколько ключей сортировки, и некоторые из них должны быть в порядке возрастания, а другие - в порядке убывания.Я думаю, что это сценарий, на который не ответил ни один из других вопросов.

В общем, вы можете использовать несколько ключей сортировки в F # с помощью кортежей.F # имеет функции List.sortBy и List.sortByDescending, которые дают вам два возможных порядка:

data |> Seq.sortByDescending (fun x -> x.FirstKey, x.SecondKey)

Однако, таким образом, порядок сортировки для обоих ключей будет одинаковым.Нет простого способа использовать один ключ в одном порядке, а другой ключ - в другом.Во многих случаях вы можете просто использовать числовой минус и сделать что-то вроде:

data |> Seq.sortByDescending (fun x -> x.FirstKey, -x.SecondKey)

Это не является полностью пуленепробиваемым из-за значений MaxInt, но, вероятно, это будет часто работать.В выражениях запросов F # (которые вдохновлены тем, как работает LINQ), вы можете использовать несколько ключей сортировки, используя sortBy и thenBy (или sortByDescending и thenByDescending):

query {
  for x in data do
  sortByDescending x.FirstKey
  thenBy x.SecondKey }

Здесь,первый ключ будет использоваться для сортировки по убыванию, и, когда имеется несколько элементов с одинаковым FirstKey, второй ключ будет использоваться для сортировки по возрастанию в этой группе.Я подозреваю, что это, вероятно, то, что вам нужно в общем случае - но, к сожалению, нет хорошего способа написать это с помощью синтаксиса конвейера.

...