views:

78

answers:

2

for F# array, is there an easy way to return sorting indices along with the sorted array? like the sort() function from Matlab?

Background: I came from matlab/R, where manipulating array on indices are essential. I'd like to reproduce some index functions and trying to be able to pass indices array around as a variable in various functions. for this sort() function, one usage would be sorting several aligned arrays together based on any one of them. Maybe there are better ways to do this?

+2  A: 

Use Array.sort in combination with Array.mapi.

let arr = [| 14;3;11;2 |]
let sortedWithIndex = arr |> Array.mapi (fun x t -> (t,x)) |> Array.sort 
printfn "%A" sortedWithIndex

output

[|(2, 3); (3, 1); (11, 2); (14, 0)|]
David Morton
Array.sort doesn't return the sorted array but sorts in place returning `unit`. The order of sorting/zipping is wrong too.
Dario
@Dario - `Array.sort` does not sort in place, it returns a new array. The aptly named `Array.sortInPlace` is used to sort an array in place. However you're right about the order of mapping and sorting being wrong.
kvb
I've corrected the order of sorting and mapping. I actually thought the OP was looking for the indexes to be applied after the sort. Oh well. Fixed now. @Dario: Array.sort does not sort in place.
David Morton
In F# 1.9.6.2 it does ;) Well, it's ok then
Dario
I guess you need to reverse x and t: Array.mapi (fun x t -> (t,x)) ?
ahala
@ahala I edited the answer to put them in the correct order. This works correctly in F# 1.9.9.9
gradbot
A: 
let sortWithIndex list =
    list
    |> List.mapi (fun index x -> (x, index))
    |> List.sort

(Depending on the version of F#, List.sort might require a comparison function like `compare ).

Dario
the last step "|> List.sort compare" gives error on my machine:error FS0001: This expression was expected to have type ('a * int) list -> 'b but here has type 'c list
ahala
`List.sort` doesn't take a comparison function (and because of the ordering of your tuple, does not need one).
kvb
@kvb: In my version it does (1.9.6.2) ;)
Dario
@Dario - fair enough. In 1.9.9.9, the function with that signature is `List.sortWith`.
kvb