How to sort a two dimensional array by columns in Javascript ?
For example, I have this 2D array, that is, a JSON array in the form of a table, and I want to sort it by columns:
var matriz = [
//Columnas: 0 1 2 3 4
/*Filas: 0*/ [9,5,3,2,7],
/* 1*/ [7,9,5,4,3],
/* 2*/ [8,4,6,0,1]
]
Accessing the element array[2][4]
returns us 1
, that is, row 2
, column 4
.
What I want to do is order, for example, the column 3
, but without changing the sequence in each row, and it would look like this:
var matriz = [
//Columnas: 0 1 2 3 4
/*Filas: 0*/ [8,4,6,0,1]
/* 1*/ [9,5,3,2,7],
/* 2*/ [7,9,5,4,3],
]
To sort the array, I use binary search. This type of search causes a value to be found in the fewest number of steps possible applied to an ordered sequence. For example, if I want to find the 66 among 100 numbers, what I do is, first, I say half of the total number, that is, I ask if it is 50. The answer to that is, "No, it is greater than 50" , then I ask the average between 50 and 100, that is, is it 75?, no, is it less, and so on.
I'm looking for 66 , I'm getting closer and closer... 100 50 75 62 68 65 66 . This is similar to what we do unconsciously when looking up a word in a paper dictionary, no one looks page by page, but rather gets closer.
What I do to order the matrix is, first I declare an empty matrix, and I insert each row in an orderly manner. In this way, the indicated column is sorted without altering the sequence in each row.
To insert a row, first I look for the indicated position to insert it, that is, the row to be inserted will be at the beginning of the matrix, or at the end, or else between two other rows.
Also, it is possible to indicate if I want to sort the array in descending order. Otherwise, it will be ascending. The function
compara
just compares two numbers. If the first is less than the second, it returns 1, if they are equal, it returns 0, and if the first is greater than the second, it returns -1... All that, if itesDescentente
isfalse
, but if it istrue
, the -1 is 1, and vice versa.Code:
In JavaScript you have the function
sort
that will sort the elements of the array you pass to it (and a two dimensional array is more than just an array of arrays), and that can take a custom comparison function as a parameter. This function will receive the arrays to be compared, so it would only be necessary to know which column index should be compared.Then you could sort the matrix by columns in a simple two-step process:
sort
with a custom sort function.Something like this (ideally the compare function should have some sort of preconditions to make sure the index and arrays are valid):
Adapting Alvaro Montoro's answer , what did not completely convince me, is that the variable
indiceOrdenacion
(in my case I name itcolumna
) receives it from nothing. So that this does not happen, I make a function that generates the functioncompare
(I name itcompara
, in Spanish).The function
genera_compara
takes two arguments, one iscolumna
, and the other isesDescendente
(a boolean), and returns a function. I leave some examples:generar_compara(3,true )
bring backfunction anonymous(a,b){return a[3]>=b[3]?1:-1}
generar_compara(4,false)
bring backfunction anonymous(a,b){return a[4]>=b[4]?-1:1}
I also made the function
ordenar
not to change the values of the original array, but to copy it.Code: