F#按索引排序

时间:2017-02-13 14:54:20

标签: f#

我们说我有两个名单:

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

现在我需要listOfValues_sorted102;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))

但我想,有更好的解决方案吗?

3 个答案:

答案 0 :(得分:6)

我认为你的解决方案非常接近。我会这样做

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

您可以将fun x -> fst x折叠为fst。然后unzip并获得您想要的列表

答案 1 :(得分:4)

如果indexesToSortBy是一套完整的索引,您只需使用:

indexesToSortBy |> List.map (fun x -> listOfValues |> List.item x )

答案 2 :(得分:3)

您的示例恰好听起来是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的索引传递到原始列表中,因此我从原始indexToSortBy列表中的所有索引中减去1。通过这两项更改,这会产生与您问题中let listOfValues_sorted = ...示例完全相同的顺序。