Undo sort on sorted array in javascript

I have the following code:

//data_r is an array with values

var i = 0;
var sort_order = new Array();

data_r.sort(function (a,b) {
    var res = a[0] - b[0];

    sort_order[i] = res;
    i++;

    return res;
});

In the end, the sort_order array contains the actions performed when we sorted items. If I want to sort a second array exactly the same way as the first then I can do the following:

//data_x is an array with values

var i = 0;
data_x.sort(function (a,b) {
    i++;
    return sort_order[i-1];
});

Now the data_x array is sorted exactly the same way as the data_r array.

The question is, how can I undo sort on the data_r array?

The following code is incorrect:

var unsort = new Array();

for(var i = 0; i < data_r.length; i++)
    unsort[i] = sort_order[i]*(-1);//-1 so we perfom the oposite action

Why, please?

EDIT:

I can’t make a copy of the array.

I have array #1. I sort it.

Then I receive array #2 but the array is sorted based on array #1.

I need to reverse the sorting on array #2.

EDIT 2:

array #1 = {9, 5, 3, 0, 2}

I sort the array #1:

array #1 = {0, 2, 3, 5, 9}

NOW i receive array #2 sorted based on array #1:

array #2 = {“home”, “car”, “train”, “pc”, “mouse”}

I need to make array #2 like this:

array #2 = {“mouse, “pc”, “train”, “home”, “car”}

solved: http://jsfiddle.net/fQm3a/

Answer

See @duskwuff’s answer on why your approach doesn’t work.

Instead, just introduce a mapping between the original data and the sorted data.

{0:2, 1:3, 2:1, 3:0}

Which means the first element became the third, the second became the last and so on. Below we’ll use an array instead of an object.

Why does this map help? You can sort it like another dataset by just using the indizes in it as pointers to the data you’re going to compare. And you can apply the mapping easily on other datasets. And you can even reverse that mapping very easily. See it in the code:

// data_r, data_x are arrays with values

var l = data_r.length;
var sort_order = new Array(l);
for (var i=0; i<l; i++) sort_order[i] = i; // initialised as 1-1 mapping

// change the sort_order first:
sort_order.sort(function (a,b) {
    // a and b being indices
    return data_r[a] - data_r[b];
});
// Making a new, sorted array
var data_x_sorted = new Array(l);
for (var i=0; i<l; i++)
    data_x_sorted[ sort_order[i] ] = data_x[i]; // put it to sorted position

If you want to sort the data_x array itself, just use the “apply” algorithm which I showed for data_r.

The question is, how can I undo sort on the data_r array?

Either don’t sort it at all, and just make a copy of it which gets sorted (or do nothing at all).

Or use the sort_order to reverse it. You just would need to swap i and newIndex (sortOrder[i]) everywhere. Example for building a new, “unsorted” (old-order) array:

var unsorted = new Array(l);
for (var i=0; i<l; i++)
    unsorted[i] = data_r[ sort_order[i] ]; // take it from its new position

Leave a Reply

Your email address will not be published. Required fields are marked *