Wais Kamal
Wais Kamal

Reputation: 6180

Two-dimensional array does not get sorted

I have an array that looks like:

[
  ["A","B","C","D"],
  ["E","F","G","H"],
  [6,43,2,4]
]

I want to sort this array in descending order of the items in the third row, such that it looks like:

[
  ["B","A","D","C"],
  ["F","E","H","G"],
  [43,6,4,2]
]

So far this is what I wrote:

var arr = [
  ["A","B","C","D"],
  ["E","F","G","H"],
  [6,43,2,4]
]

arr = arr.sort((a,b) => {
  return b[2] - a[2]
});

console.log(arr);

But the array does not get sorted. Where did I go wrong?

Upvotes: 0

Views: 69

Answers (4)

David Kirk
David Kirk

Reputation: 342

It would be easier if you could depict the data differently. The Array.sort function will not help you with your current example.

var arr = [{
    a: "A", b: "E", c: 6
},{
    a: "B", b: "F", c: 43
},{
    a: "C", b: "G", c: 2
},{
    a: "D", b: "H", c: 4
}]

arr.sort((a, b) => {
    return b.c - a.c;
})

console.log(arr);

If you can't, I could provide a different answer; but the answer would be very inefficient.

Upvotes: 1

John Coleman
John Coleman

Reputation: 51998

You want to sort columns. It is easier to sort rows. So, you could transpose then sort then retranspose:

const arr = [
  ["A","B","C","D"],
  ["E","F","G","H"],
  [6,43,2,4]
];

const transpose = array => array[0].map((col, i) => array.map(row => row[i]));

const t = transpose(arr);
t.sort((rowi,rowj) => (rowj[rowj.length - 1] - rowi[rowi.length-1]));
console.log(transpose(t));

Which has the intended output of:

[ [ 'B', 'A', 'D', 'C' ],
  [ 'F', 'E', 'H', 'G' ],
  [ 43, 6, 4, 2 ] ]

This is clearly not as efficient as the other answers, but the fact that you are asking the question suggests that your current way of storing the data isn't convenient for your purposes. Perhaps you might want to transpose then skip the retranspose part.

Upvotes: 2

jcubic
jcubic

Reputation: 66488

You need to first sort the number store indexes and then sort the other arrays.

var arr = [
  ["A","B","C","D"],
  ["E","F","G","H"],
  [6,43,2,4]
]

var tmp = arr[2].map((value, i) => ({value, i})).sort((a, b) => b.value - a.value);

arr = arr.map(function(arr) {
  return tmp.map(({value, i}) => arr[i]);
});

console.log(arr);

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386560

You could take the indices of the array for sorting, sort this array by the values of the original array and map all reordered items.

var array = [["A", "B", "C", "D"], ["E", "F", "G", "H"], [6, 43, 2, 4]],
    indices = [...array[2].keys()].sort((a, b) => array[2][b] - array[2][a]);

array = array.map(a => indices.map(i => a[i]));

console.log(array.map(a => a.join(' ')));

Upvotes: 3

Related Questions