Sort 2 array by column, as a parameter in a function

77 views Asked by At

I can sort an array by column with this answer It looks a bit like this:

var myArr = [ [0, 10, 20, "jam"], [1, 20, 14, "carrots"], [2, 30, 14, "custard"], [3, 40, 16, "beef"], [4, 0 , 16, "gwen"], ]

myArr.sort(sort_2d_array);

function sort_2d_array(arr) 
{

  var column = 1;

  if (a[column] === b[column]) 
  {
    return 0;
  }
  else
  {
    return (a[column] < b[column]) ? -1 : 1;
  }
}

Which gets sorted as: 4, 0 , 16, "gwen" 0, 10, 20, "jam" 1, 20, 14, "carrots" 2, 30, 14, "custard" 3, 40, 16, "beef"

However, since it's written as a function expression, how do I write it if I wanted to pass column as a parameter into the function? Without having 4 versions of the same function with a different value vorm column.

Personally, I'd find it easier to comprehend and understand in the traditional form:

function sort_2d_array_by_column(arr, column) 

Or is that putting the cart before the horse?

If this doesn't make sense, I'll have another go at writing it. #spectrumofconfusion

2

There are 2 answers

1
Nina Scholz On

You could take a closure over the index and return the sorting function as callback.

var sortByIndex = function (index) {
        return function (a, b) {
            return (a[index] > b[index]) - (a[index] < b[index]);
        };
    },
    array = [[0, 10, 20, "jam"], [1, 20, 14, "carrots"], [2, 30, 14, "custard"], [3, 40, 16, "beef"], [4, 0, 16, "gwen"]];

array.sort(sortByIndex(1));
console.log(array);

array.sort(sortByIndex(3));
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

0
georg On

Let's have some functional programming here:

const cmp = (a, b) => (a > b) - (a < b)
const column = p => o => o[p]
const by = f => (x, y) => cmp(f(x), f(y))


myArr = [
    [0, 10, 20, "jam"],
    [1, 20, 14, "carrots"],
    [2, 30, 14, "custard"],
    [3, 40, 16, "beef"],
    [4, 0, 16, "gwen"],
]

myArr.sort(by(column(2)));
console.log(myArr.map(JSON.stringify))


myArr.sort(by(column(3)));
console.log(myArr.map(JSON.stringify))

A less "advanced", but perhaps more readable (and ES3 compatible) version:

function sortByColumn(arr, col) {
    return arr.sort(function(x, y) {
        x = x[col]
        y = y[col]
        return (x > y) ? 1 : (x < y ? -1 : 0)
    })
}