1

I want to sort a 2D array first by column 5, then by column 4. They represent the PTS and GD on a football league table.

var table = [
  ["teamA", 6, 2, 0, 2, 7],
  ["teamB", 6, 1, 1, 6, 7],
  ["teamC", 6, 2, 1, 8, 7]
];

I've adapted the great advice I received on the forum: Sorting 2D Array by numeric item

I replicated the function so that it first sorts by PTS and then by GD.

console.log(table.sort(comparePTS));

console.log(table.sort(compareGD));

function comparePTS(a, b) {
  return b[5] - a[5]

}
function compareGD(a, b) {
  return b[4] - a[4]
}

Although this works, it displays the table twice:

Sorted by PTS

[ [ "teamA", 6, 2, 0, 2, 7 ], [ "teamB", 6, 1, 1, 6, 7 ], [ "teamC", 6, 2, 1, 8, 7 ] ]

Sorted by PTS and GD

[ [ "teamC", 6, 2, 1, 8, 7 ], [ "teamB", 6, 1, 1, 6, 7 ], [ "teamA", 6, 2, 0, 2, 7 ] ]

And this seems the most clunky solution. What's the best way to achieve this within a single function? Thanks in advance.

gdh48k
  • 29
  • 6

1 Answers1

0

You could chain the order functions until you have a difference for returning this value to the sorting function.

const
    PTS = a => a[5],
    GD = a => a[4],
    ASC = fn => (a, b) => fn(a) - fn(b),
    DESC = fn => (a, b) => fn(b) - fn(a),
    sortBy = fns => (a, b) => {
        var value;
        fns.some(fn => value = fn(a, b));
        return value;
    };

var table = [["teamA", 6, 2, 0, 2, 7], ["teamB", 6, 1, 1, 6, 7], ["teamC", 6, 2, 1, 8, 7]];
   
table.sort(sortBy([DESC(PTS), DESC(GD)]));

console.log(table);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Thank you Nina. I am very grateful for your reply. A second answer was posted earlier, however, that appeared simpler but has now been removed. It modifyed the original compare function with 'or' operator for the two sort conditions - I wonder if this could be re-posted? – gdh48k May 26 '19 at 18:09
  • the main part was to use `first-comparison || second-comparison` with `table.sort((a, b) => b[5] - a[5] || b[4] - a[4]);`. – Nina Scholz May 26 '19 at 18:23
  • Thank you so much, Nina. I've just tried that and it works a treat! For my understanding, is `table.sort((a, b) => b[5] - a[5] || b[4] - a[4]);` simply a more concise version of your code or is it fundamentally different? – gdh48k May 26 '19 at 18:39
  • it is a hard coded version of mine. If you have some more sorting needs, then a dynamic approach could be better. – Nina Scholz May 26 '19 at 18:43
  • Thanks again. And finally, if the hardcoded version is a so-called arrow function, is the name of the function 'table.sort'? Only I had thought 'table.sort' was an in-built method? Apologies for all the questions. – gdh48k May 26 '19 at 18:52
  • [`Array#sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) is a function of an array which takes a function and returns a value, depending on the values for sorting. – Nina Scholz May 26 '19 at 18:53