2017-02-13 4 views
4

Скажем, у меня есть два списка:F # сортировать по индексам

let listOfValues = [100..105] //can be list of strings or whatever 
let indexesToSortBy = [1;2;0;4;5;3] 

Теперь мне нужно listOfValues_sorted: 102;100;101;105;103;104

Это может быть сделано с zip и "преобразования" в кортежей:

let listOfValues_sorted = listOfValues 
         |> Seq.zip indexesToSortBy 
         |> Seq.sortBy(fun x-> fst x) 
         |> Seq.iter(fun c -> printfn "%i" (snd c)) 

Но я думаю, есть лучшее решение для этого?

+0

Обратите внимание, что ваш пример вывода '' listOfValues_sorted' является 102; 100; 101; 104; 105; 103', но образец код, который вы даете, будет ** фактически ** производить '102; 100; 101; 105; 103; 104'. Я считаю, что последнее - это то, что вы действительно хотите, так вот как я ответил на ваш вопрос. – rmunn

ответ

6

Я думаю, что ваше решение довольно близко. Я хотел бы сделать это

let listOfValues_sorted = 
    listOfValues 
    |> Seq.zip indexesToSortBy 
    |> Seq.sortBy fst 
    |> Seq.toList 
    |> List.unzip 
    |> List.head 

вы можете свернуть fun x -> fst x в просто fst. А потом unzip и получить то, что когда-либо список, который вы хотите

+0

Fine.Thnx. Другим упрощением может быть только использование списка. Но есть проблема с «не такой же длиной» последовательностей (Seq отлично с разной длиной?). Вопрос обновлен -> Списки имеют одинаковую длину (оригинальная цель). – Alamakanambra

+0

Я считаю, что 'List.permute' - лучшее решение. – rmunn

2

Ваш пример звучит именно то, что List.permute function для:

let listOfValues = [100..105] 
let indexesToSortBy = [|1;2;0;4;5;3|] // Note 0-based indexes 

listOfValues |> List.permute (fun i -> indexesToSortBy.[i]) 
// Result: [102; 100; 101; 105; 103; 104] 

Две вещи: во-первых, я сделал indexesToSortBy это массив, так как я буду смотреть на значение внутри него N раз, и выполнение этого в списке приведет к времени выполнения O (N^2). Во-вторых, List.permute ожидает, что в исходный список будет передан индекс, основанный на 0, поэтому я вычитал 1 из всех индексов в вашем исходном списке indexToSortBy. При этих двух изменениях это производит точно такой же порядок, что и пример let listOfValues_sorted = ... в вашем вопросе.

4

Если indexesToSortBy представляет собой полный набор индексов вы могли бы просто использовать:

indexesToSortBy |> List.map (fun x -> listOfValues |> List.item x) 
Смежные вопросы