score:0

while reading other answers i got a little confused about which `indexes` order you want exactly, but here's solution if you want them to in order `1 2 0` as you posted in your question. try this:

``````var a = new int[] { 2, 3, 1 };
var indexes = new int [a.length];

var sorted = a.orderby(n => n)
.select((n, i) =>
{
indexes[array.indexof(a, n)] = i;

return n;
})
.toarray();
``````

score:1

another working solution:

``````var input = new list<int> { 2, 3, 1 };
var result = input.select(x => input.orderby(n => n).tolist().indexof(x));

console.writeline(string.join(" ", result));  // 1 2 0
``````

score:4

one way to do this is as follows:

``````int[] a = {2, 3, 1};
int[] b = enumerable.range(0, a.length).toarray();
int[] c = new int[a.length];

array.sort(a, b);

for (int i = 0; i < b.length; ++i)
c[b[i]] = i;

console.writeline(string.join(", ", c)); // prints 1, 2, 0
``````

it uses the overload of `array.sort()` which sorts one array using the values from a different array.

i think this is fairly efficient: it uses a o(n log(n)) sort and an o(n) remapping. (the other correct solutions are o(n log(n)) plus o(n^2))

it only works with arrays, however (because there is no equivalent of `array.sort()` for list).

an alternative using linq (and effectively an amendment to @nawfal's answer):

``````int[] a = {2, 3, 1};

var b = a
.select((item, index) => new { item, index })
.orderby(x => x.item)
.select(x => x.index)
.toarray();

int[] c = new int[b.length];

for (int i = 0; i < b.length; ++i)
c[b[i]] = i;

console.writeline(string.join(", ", c)); // prints 1, 2, 0
``````

the crucial thing here is the additional mapping step in both approaches:

``````int[] c = new int[b.length];

for (int i = 0; i < b.length; ++i)
c[b[i]] = i;
``````

this is effectively a reverse-lookup mapping.

score:8

you could do this with a linq select:

``````var a =new [] {2,3,1};

var sorted = a.orderby (x => x).tolist();
var indexes = a.select (x => sorted.indexof(x));
``````

if this is a huge list rather than this simple one it might be a little inefficient but does return what you are expecting.

score:23

## note:

i made a terrible mistake of misreading op's question (and embarrassed this received so many upvotes). i wished (ideally) op accepts one of the other answers as correct. to do justice to the upvoters and in spirit of so, i will amend this answer to make it correct.

one could carry two extension methods, one for old indices and one for new indices (which is what op wants).

``````public static ienumerable<int> oldindicesifsorted<t>(this ienumerable<t> source) where t : icomparable<t>
{
return source
.select((item, index) => new { item, index })
.orderby(a => a.item)
.select(a => a.index);
}

public static ienumerable<int> newindicesifsorted<t>(this ienumerable<t> source) where t : icomparable<t>
{
return source
.oldindicesifsorted()
.select((oldindex, index) => new { oldindex, index })
.orderby(a => a.oldindex)
.select(a => a.index);
}
``````

call it like,

``````//a = [2, 3, 1];
a.newindicesifsorted(); // should print [1, 2, 0]
``````

the two methods are lazy, but `newindicesifsorted` should ideally be written according to matthew watson's answer which is simply more efficient. the plus side of both mine and mat's answer is that is handles duplicate entries well.