12
Feb

Sorting multi-dimensional JavaScript arrays

   Posted by: Grumelo   in javascript, web

Sorting an array in JavaScript is done with <array>.sort()

sort() explanation in French
sort() explanation in English

It’s very easy and well explained in all JavasScript references.
When dealing with two-dimensional arrays or even worst with multi-dimensional arrays it’s another story.
Let me try to explain you thanks to clear examples.

How to sort a two-dimensional array ?

Let me explain it with simple examples.

Two-dimension data structure

var myArray = [
[“DVD Title 1″,”label1″,”releasedate2″,”details1”],
[“DVD Title 1″,”label3″,”releasedate1″,”details1”],
[“DVD Title 1″,”label3″,”releasedate2″,”details1”],
[“DVD Title 1″,”label2″,”releasedate1″,”details1”],
[“DVD Title 1″,”label1″,”releasedate1″,”details1”],
[“DVD Title 2″,”label2″,”releasedaten”,”detailsn”],
[“DVD Title 2″,”label1″,”releasedaten”,”detailsn”]
];

Custom sort function to use

Example 1

If you want to sort by by all four elements of the sub arrays, you would use the following…

myArray.sort(mySorting);

function mySortingA(a,b) {
a = a[0]+a[1]+a[2]+a[3];
b = b[0]+b[1]+b[2]+b[3];
return a == b ? 0 : (a < b ? -1 : 1)
}

result = myArray.join(‘\n’);
alert(result);

Example 2

If you want to sort by only the second element, lable or [1], you would use the following…

function mySorting(a,b) {
a = a[1];
b = b[1];
return a == b ? 0 : (a < b ? -1 : 1)
}

Example 3

If you want to sort by the second element, lable or [1], and the third element, releasedate or [2], you would use the following…

function mySorting(a,b) {
a = a[1]+a[2];
b = b[1]+b[2];
return a == b ? 0 : (a < b ? -1 : 1)
}

Explanation about ‘a’ and ‘b’

‘a’ and ‘b’ are set to what you want to use for comparison.
‘a’ and ‘b’ are two special reserved variables that represent elements to be sorted.
‘a’ and ‘b’ are  represent the 1st & 2nd, 2nd & 3rd, 3rd & 4th, etc., elements to compare.

It’s good practice NEVER to use ‘a’ and ‘b’ as variables in your scripts.

The custom sorting function (called mySorting in the examples) needs to return -1, 0, or 1 to give you the sort order.
a < b returns -1
a = b returns 0
a > b returns 1

or to reverse the order
a < b returns 1
a = b returns 0
a > b returns -1

Ascending and descending sorting

A custom sorting function that ends with: return a == b ? 0 : (a < b ? -1 : 1) is ascending (Asc)

A custom sorting function that ends with: return a == b ? 0 : (a < b ? 1 : -1) is descending (Desc)

Sorting multi-dimentional arrays

Multi-dimensional data structure

var myArray = [
[[“DVD Title 1″,”label1″,”releasedate2″,”details1”],’Ref001′,[‘Me’,[‘2006′,’02’,’28’,’16:30′]]],
[[“DVD Title 1″,”label3″,”releasedate1″,”details1”],’Ref002′,[‘Me’,[‘2006′,’06’,’11’,’11:30′]]],
[[“DVD Title 1″,”label3″,”releasedate2″,”details1”],’Ref003′,[‘Us’,[‘2007′,’02’,’28’,’09:30′]]],
[[“DVD Title 1″,”label2″,”releasedate1″,”details1”],’Ref005′,[‘Us’,[‘2006′,’06’,’15’,’16:00′]]],
[[“DVD Title 1″,”label1″,”releasedate1″,”details1”],’Ref004′,[‘He’,[‘2007′,’02’,’28’,’12:30′]]],
[[“DVD Title 2″,”label2″,”releasedaten”,”detailsn”],’Ref007′,[‘He’,[‘2008′,’02’,’28’,’13:30′]]],
[[“DVD Title 2″,”label1″,”releasedaten”,”detailsn”],’Ref006′,[‘We’,[‘2008′,’05’,’28’,’16:30′]]]
];

Data structure can be understand as list of DVD and for every DVD you have:

  • several columns used to describe the DVD like title, label, release date and details
  • the unique ID, the Reference of the DVD
  • some metadata like a owner and a date splitted in year, month, day and time

This data data structure has from 2 to 4 dimensions:

  • info about the DVD are stored in the third dimension
  • the unique id in the second dimension
  • the date in the metadata in the fourth dimension

Different examples of sorting

Example 1

If you want to sort by References and in the reverse order, you would use the following…

function mySorting(a,b) {
a = a[1];
b = b[1];
return a == b ? 0 : (a < b ? 1 : -1)
}

The expected Reference sequence is: 7 6 5 4 3 2 1

Example 2

If you want to sort by Labels, you would use the following…

function mySorting(a,b) {
a = a[0][1];
b = b[0][1];
return a == b ? 0 : (a < b ? -1 : 1)
}

The expected Reference sequence is: 1 4 6 5 7 2 3

Example 3

If you want to sort by the descending date in the metaData part of the data (column 3 of the data about a DVD, means a fourth dimension), you would use the following…

function value(a,b) {
a = a[2][1][0]+a[2][1][1]+a[2][1][2];
b = b[2][1][0]+b[2][1][1]+b[2][1][2];
return a == b ? 0 : (a < b ? 1 : -1)
}

The expected Reference sequence is: 6 7 3 4 5 2 1

Example 4

If you want to sort by the descending date and time in the metaData part of the data (second element of column 3 of the data about a DVD, means a fourth dimension), you would use the following…

function value(a,b) {
a = a[2][1][0]+a[2][1][1]+a[2][1][2]+a[2][1][3];
b = b[2][1][0]+b[2][1][1]+b[2][1][2]+b[2][1][3];
return a == b ? 0 : (a < b ? 1 : -1)
}

The expected Reference sequence is: 6 7 4 3 5 2 1

Tips to create the ‘a’ and ‘b’ sequence

It’s not very easy to find the right way of writing the ‘a’ and ‘b’ sequences.
If you can find ‘a’, ‘b’ should not be a problem 😀

The idea is to find how will write the code to access the first entry of the element you want to sort by?

If you are looking for the Reference code in your data you will write something like this:

var myReference = myArray[0][1];

In the sorting function it becomes: a[1] and b[1]

If you are looking for the Label in your data you will write something like this:

var myReference = myArray[0][0][1];

In the sorting function it becomes: a[0][1] and b[0][1]

The time in the metaData is accessed with: var myTime = myArray[0][2][1][3];

In the sorting function its: a[2][1][3] and b[2][1][3]

Test page

You can use this test page to perform your own testing because of course your data structure will be different than the one provided in the examples.

Coming soon…

References

Evaluation: Pas terribleAssez bienBienSuper!Excellent! (11 votes)
Loading...

Tags: , , ,

This entry was posted on Thursday, February 12th, 2009 at 18:35 and is filed under javascript, web. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

16 comments so far

smartwork
 1 

Really nice explanation, but it took a little more time to understand 😉 my multi dimentional array, Keep the good post.

March 5th, 2009 at 14:12
 2 

Do you want help with your array ?

March 5th, 2009 at 16:08
Toby
 3 

Very helpful, but I seem to have a bug (IE) when trying to loop through a 2-dim object array to unpack sorted data to a table. Usual 2 loops to iterate through each row and then through each row’s cells, but the row counter for the array won’t proceed further than row 0 so array ‘row 0’ textNode contents copy to all other table rows. The sorted array’s fine and copying across using hardwired indices works okay, just the array row index sticks even if I remove the row loop and simply repeat blocks of cell iterations for each literal row index! Is there a known JavaScipt bug with looping through object arrays like this? I’ve tried everything and headbanging’s getting painful!

May 1st, 2009 at 03:16
Vaidy
 4 

Pleasant website and nice example

October 7th, 2009 at 16:56
Wally
 5 

OK, that’s cool. Now, how do I pass an array element to sort on to the mySorting function? Do I just have to use a global? Let’s say I want to sort on the 3rd element one time and the 2nd another time?

January 15th, 2010 at 18:53
Wally
 6 

Oh, and do me a favor and respond to my email address.

January 15th, 2010 at 18:54
Wally
 7 

Never mind – found it in one of your references…NOW I understand how this works…

January 15th, 2010 at 19:02
Sylvain
 8 

array.sort( sort_by( “myfield” );
or
array.sort( sort_by([“myfield1″,”myfield2″,”myfield3”];

the code is below:

function sort_by(field_names) {

if( typeof field_names == “string” ) {
field_names = [ field_names ];
}

return function (a, b) {
for( var i=0 ; i<field_names.length ; i++ ) {
var field_name = field_names[i];
if( a[field_name] b[field_name] ) return 1;
}

return 0;
};
}

January 16th, 2010 at 13:57
Sylvain
 9 

the function I posted above is to sort an array on multiple variables, means to sort the list by the “name” (col 1) and the date (col 3)

I personally don’t concatenate the value in a sort function, the concat is *very* slow, and the sort function will be called at least n log(n) times if not n^2

I prefer to create a new variable that will be used by the sort:
for( var i = 0 …. over my array) {
// a new variable to sort my array
MyArray.push( myArray[0][1]+myArray[0][2]+myArray[0][3])
}

and I sort the array by doing for instance:

// sort on 2 variables (name & date for instance)
myArray.sort ( sort_by( [1,5] ) );

hope it is clear for all.

Best regards,
Sylvain

January 16th, 2010 at 14:11
Lukus
 10 

Grumelo, thanks for sharing.
Sylvain, I liked your approach so that the choice of columns can be dynamically built.

Grouping the concepts together, I came up with this solution that worked well for me:

var fieldsToSortBy = [0,2,5,4];

myArray.sort(sortBy(fieldsToSortBy));

function sortBy(fields) {
return function (a, b) {
var A;
var B;
for( var i=0 ; i< fields.length ; i++ ) {
A += a[fields[i]];
B += b[fields[i]];
}
return A == B ? 0 : (A < B ? -1 : 1)
};
}

…though I realize it doesn't avoid the concatenation… couldn't get it to work correctly with the other example, speed doesn't appear to be an issue either.

Good luck!

January 21st, 2010 at 10:39
Torrey
 11 

Thank you for taking the time to post this information. I’m sure a lot of people have used this to help themselves and did not expresses their gratitude.

February 10th, 2011 at 10:23
Quaziz
 12 

The problem with this sort function is that integers are not well treated.
if you have a series of number as follows:
1,2,3,4,5,6,7,8,40.
The sort function will present it like this:
1,2,3,4,40,5,6,7,8
Its a realy simpel way of treating multi-dimensional arrays. I know that. There are more inteligent scripts out there. If you can provide it with more inteligence in the sorting process it will be of much more help to many more. Maybe currency support also would be good to implement.

March 10th, 2011 at 15:01
Rams
 13 

Can anyone tell how to implement this for numbers?

April 30th, 2011 at 19:16
OscarB
 14 

Muchas Gracias. =) justo lo que buscaba.

January 8th, 2013 at 19:50
Cohoman
 15 

Thanks for the great tips on sorting multidimensional arrays. It came in handy for one of my projects! Much appreciated.

January 14th, 2013 at 05:33
Triple-C™ (Ciamis Cyber Community)
 16 

Fantastic beat ! I would like to apprentice even as you amend your website, how can i subscribe for a weblog website? The account helped me a applicable deal. I had been tiny bit acquainted of this your broadcast offered vibrant clear idea

May 24th, 2013 at 12:29

3 Trackbacks/Pings

  1. Qr Code Generator    Oct 04 2011 / 4am:

    Qr Code Generator…

    […]Grumelo’s Realm » Blog Archive » Sorting multi-dimensional JavaScript arrays[…]…

  2. 电动调压器    Oct 18 2011 / 2pm:

    电动调压器…

    […]Grumelo’s Realm » Blog Archive » Sorting multi-dimensional JavaScript arrays[…]…

  3. 电动调压器型号    Oct 19 2011 / 8am:

    电动调压器供应商…

    […]Grumelo’s Realm » Blog Archive » Sorting multi-dimensional JavaScript arrays[…]…

Leave a reply

Name (*)
Mail (will not be published) (*)
URI
Comment