1

So, I have this array:

distances = [[Obj1, Obj2, Obj3, Obj4], [15,221,9,2]];

I want to sort the two dimensional array based on the second array so it should look like this:

distances = [[Obj4, Obj3, Obj1, Obj2], [2, 9, 15, 221]];

I know I can use this method: How to sort 2 dimensional array by column value?, but I can't seem to adapt the code.

Community
  • 1
  • 1
nick
  • 2,819
  • 5
  • 33
  • 69
  • you should prefer a single Array of Objects over multiple Arrays *(one Array per property)* that you have to keep sync. `distances = [{ obj: Obj1, dist: 15}, { obj: Obj2, dist: 221}, { obj: Obj3, dist: 9}, { obj: Obj4, dist: 2}]` It's easier to handle and you avoid synchronisation problems. – Thomas Sep 30 '16 at 22:45

4 Answers4

4

First, a rather unefficient solution would be to transpose your array to match the layout of the solution you linked in your question.

var temp = [];
for(var i in distances[0])
  temp[i] = ([distances[0][i], distances[1][i]]);

Then do the sorting and transform it back to its previous form:

distances = [[], []];
for (var i in temp) {
  distances[0][i] = temp[i][0];
  distances[1][i] = temp[i][1];
}
jan
  • 81
  • 3
3

You could use a temporary array for the sort order and apply this to the two arrays of distances.

var distances = [['Obj1', 'Obj2', 'Obj3', 'Obj4'], [15, 221, 9, 2]],
    order = distances[0].map(function (_, i) { return i; });

order.sort(function (a, b) {
    return distances[1][a] - distances[1][b];
});

distances[0] = order.map(function (i) { return distances[0][i]; });
distances[1] = order.map(function (i) { return distances[1][i]; });

console.log(distances);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
3
var sorted = distances[1].map(function (v, i) { 
   return {v:v,i:i,o:distances[0][i]} }).
      sort(function (a,b) { return a.v - b.v});
distances[0] = sorted.map(function (x) { return x.o });
distances[1] = sorted.map(function (x) { return x.v });
Keith
  • 22,005
  • 2
  • 27
  • 44
2

var distances = [["Obj1", "Obj2", "Obj3", "Obj4"], [15,221,9,2]];

var NewDistances = [];
for (var i = 0; i < distances[0].length; i++)
  NewDistances[i] = {
    Obj: distances[0][i],
    Key: distances[1][i]
  };
NewDistances.sort(function(O1, O2) {
  return O1.Key < O2.Key ? -1 : (O1.Key > O2.Key ? 1 : 0);
});
var Result = [[],[]];
for (var i = 0; i < NewDistances.length; i++) {
  Result[0][i] = NewDistances[i].Obj;
  Result[1][i] = NewDistances[i].Key;
}

console.log(Result);
Andrew Bone
  • 7,092
  • 2
  • 18
  • 33
Dakusan
  • 6,504
  • 5
  • 32
  • 45
  • It wasn't me, this was the answer that I'll use, thank you! – nick Sep 30 '16 at 22:43
  • Sure, and thanks! The .map ones are good too, I didn't use that due to its incompatibility in internet explorer 6-8 – Dakusan Sep 30 '16 at 22:44
  • IE 6-8, even Microsoft has abandoned it. (no support).. For security reasons best avoided.. If really required, I'd personally use a polyfill than suffer.. :) – Keith Sep 30 '16 at 22:51
  • I use jQuery myself to keep compatibility higher. Unfortunately, there are still many companies stuck on lower verisons of IE – Dakusan Sep 30 '16 at 22:53