...

# Sorting a multi-dimensional array

Gez
08-13-2008, 09:15 PM
Is it possible to use the .sort() function to sort a multi-dimensional array? if so, how? if not, how could i do it?

Thanks
Gez

ninnypants
08-13-2008, 09:47 PM
I think it would depend on how you want to use it. What exactly are you trying to do?

Trinithis
08-13-2008, 09:52 PM
Something like this? (Untested)

if(!Array.prototype.map)
Array.prototype.map = function(f /*, context */) {
for(var r = [], i = 0, n = this.length, t = arguments[1]; i < n; ++i)
r[i] = f.call(t, this[i], i, this);
return r;
};

function comparator(a, b) {
if(a > b)
return 1;
if(a < b)
return -1;
return 0;
}

function map(f, arr) {
var map = function(arr) {
return arr.map(f);
};
return arr
? map(arr)
: return map
;
}

function iterate(f, z, n) {
return n > 0
? iterate(f, f(z), n - 1)
: z
;
}

var foo = some array
var dim = the dimension of foo

var sortedFoo = iterate(map, function(arr) {
arr.sort(comparator);
}, dim - 1)(foo);

liorean
08-13-2008, 10:14 PM
It's entirely possible to do. It all depends on the function you pass as argument into sort. It can be somewhat tricky sometimes however, depending on exactly which manner you want to sort the array in and whether you need to move values between subarrays or not. It also depends on the kind of data you want sorted. Remember also that the sort function is not guaranteed to be a stable sort, which means that if you sort two items as equal the order in which they will be sorted may be any which way. Also remember that sort requires a sorting function that gives a so called total ordering: if you have a value you must always be able to say whether it is greater than, less than or equal to any other value, and the comparison must be consistent regarding all elements in the array.

jkd
08-13-2008, 11:10 PM
Remember also that the sort function is not guaranteed to be a stable sort, which means that if you sort two items as equal the order in which they will be sorted may be any which way.

Firefox 3 (https://bugzilla.mozilla.org/show_bug.cgi?id=224128), IE, and Safari all implement stable sorts, while it seems Opera does not. (If anybody is interested.)

liorean
08-14-2008, 12:05 AM
Firefox 3 (https://bugzilla.mozilla.org/show_bug.cgi?id=224128), IE, and Safari all implement stable sorts, while it seems Opera does not. (If anybody is interested.)I knew both gecko1.8 and op did unstable, didn't know they changed sorting algorithm for gecko1.9 however... (And of course I'm interested in things like this...)

I can imagine op being very skeptical about changing to a stable sort. The op devs have very strong memory footprint constrains, and chanigng an O(1) footprint into O(n) (which would be necessary to maintain performance when making the sort stable) seems like something that wouldn't go well on mobile platforms that are already footprint constrained.

Gez
08-14-2008, 02:39 AM
well this is my code :

<html>
<body>

<script type="text/javascript">
// define the catalogue
var catalogue= new Array();
catalogue[0]= new Array(3765834619,"Neuro-linguistic Programming for Dummies",12.99,950);
catalogue[1]= new Array(5673423435,"Excel 2007 VBA Programming for Dummies",11.99,900);
catalogue[2]= new Array(7454982674,"The Forgotten Garden",9.99,450);
catalogue[4]= new Array(1629546824,"No Time For Goodbye",10.99,600);
catalogue[5]= new Array(3547975624,"The Outcast",10.99,670);
catalogue[6]= new Array(1348795463,"How to Write Songs on Guitar",15.99,1010);
catalogue[8]= new Array(2730471465,"Management and Organisational Behaviour",20.99,1000);
catalogue[10]= new Array(8455327034,"AA pocket world atlas",10.99,1000);
catalogue[11]= new Array(7004367823,"The Years of Extermination ",8.99,450);
catalogue[12]= new Array(6723002893,"Eden's Outcasts",10.99,900);
catalogue[13]= new Array(5749438430,"What God Hath Wrought",10.99,800);
catalogue[14]= new Array(6758465435,"Time and Materials",10.99,760);
catalogue[15]= new Array(4356358907,"The Brief Wondrous Life of Oscar Wao",7.99,350);
catalogue[16]= new Array(5837593750,"Harry Potter and the Deathly Hallows ",9.99,900);
catalogue[17]= new Array(5759375974,"The World Without Us ",12.99,700);
catalogue[18]= new Array(5847594738,"The Dangerous Book for Boys ",17.99,780);
catalogue[19]= new Array(1477837381,"Deceptively Delicious",14.99,654);
catalogue[21]= new Array(7666834290,"Legacy of Ashes",11.99,1200);

// declare variables used throughout the program
var isbn;
var bookamount;
var title;
var quantity;
var temporder = new Array();
var order = new Array();
var showorder;
var weight;
var totalweight;
var weightcost;
var price;
var totalbookcost;
var totalcost;

// function to get the order from the user
function get_order (){

// see how many books they want overall
bookamount = prompt("How many books would you like to order altogether?:");

for ( c = 0; c < bookamount ; c++){

// get the isbn number + quantity
isbn = prompt("Please enter the ISBN number of the book you wish to order(10-digit code):");
isbn = parseInt(isbn);
quantity = prompt("Quantity?:");
quantity = parseInt(quantity);

// assign values to the orders array
temporder [c]= new Array ( isbn, quantity );

}

}

// function to get the details of the order
function get_order_details(){
// loop that goes through the order array
for ( x=0 ; x < temporder.length ; x++){

var x2 = x
// loop that locates the books details
for (i=0 ; i < catalogue.length ; i++){

var isbnspecific = parseInt(catalogue[i][0]);

if ( temporder[x][0] == isbnspecific ) {

// weight
weight = catalogue[i][3];
// price
price = catalogue[i][2];
// title
title = catalogue[i][1];
// isbn
isbn = catalogue[i][0];
// quantity
quantity = temporder[x][1]

// assign the details to the array
order[x]= new Array ( isbn, quantity, title, price, weight );

}
}
}

}

// function to calculate all the relevent costs
function work_out_costs(){

// work out postage costs
totalweight = 0;

for ( q = 0 ; q < order.length ; q++){

totalweight += (parseInt(order[q][4]) * parseInt(order[q][1]));

}

if ( totalweight >= "1" && weight <= "500" )

weightcost = "1";

if ( totalweight >= "501" && weight <= "1000" )

weightcost = "2";

if ( totalweight >= "1001" && weight <= "2000" )

weightcost = "3";

if ( totalweight >= "2001" && weight <= "5000" )

weightcost = "4";

if ( totalweight >= "5001")

weightcost = "5";

// work out total book cost
totalbookcost = 0;

for ( w = 0 ; w < order.length ; w++ ){

totalbookcost += (parseFloat(order[w][3]) * parseFloat(order[w][1]));

}

// round the value to 2.d.p

totalbookcost = Math.round(totalbookcost*100)/100;

// work out total costs

totalcost = parseFloat(totalbookcost) + parseFloat(weightcost);

// round the value to 2.d.p

totalcost = Math.round(totalcost*100)/100;

}

function sort_orderarray (){

}

// function to display all the order details
function display_order(){

showorder = "Order: " + '\n' + '\n';
// loop to go through orders array and get the details
for (z = 0 ; z < order.length ; z++){
showorder += order[z][0] + " | " +order[z][2] + " | £"
+order[z][3] + " | " + order[z][4] +"g x " + order[z][1] + '\n';
}
showorder += "--------------------------------------------------------------------" + '\n' +
'\n' + "Sub Total: £" + totalbookcost +'\n' +
"Total weight: " + totalweight + "g" + '\n'+
"P&P: £" + weightcost + ".00" + '\n' +
"Total cost: £" + totalcost;

}

get_order();

get_order_details();

work_out_costs();

display_order();

</script>

</body>
</html>

the array i need sorted is the 'order' and it need to be sorted by ISBN number so that when it comes to showing the order at the end the items are inorder by ISBN, is it possible to do this using the sort function??

Gez.

ninnypants
08-14-2008, 02:53 AM
I believe that it will do what you need without anything then but it may end up that you have to create a function that compares numbers

Trinithis
08-14-2008, 02:56 AM
catalogue.sort(function(a, b) {
return a[0] < b[0]
? -1
: a[0] == b[0]
? 0
: 1
;
});

But you probably shouldn't be using an array to represent a book. Consider something like:

function Book(isbn, title, dewey, something) {
this.isbn = isbn;
this.title = title;
this.dewey = dewey;
this.something = something;
}

var catalogue = [
new Book(3765834619, "Neuro-linguistic Programming for Dummies", 12.99, 950)
, new Book(5673423435, "Excel 2007 VBA Programming for Dummies", 11.99, 900)
, new Book(7454982674, "The Forgotten Garden", 9.99, 450)
, new Book(8356583865, "The Road Home", 9.99, 500)
, new Book(1629546824, "No Time For Goodbye", 10.99, 600)
, new Book(3547975624, "The Outcast", 10.99, 670)
, new Book(1348795463, "How to Write Songs on Guitar", 15.99, 1010)
, new Book(5673519472, "Fretboard Roadmaps", 12.992, 2700)
];

catalogue.sort(function(a, b) {
return a.isbn < b.isbn
? -1
: a.isbn == b.isbn
? 0
: 1
;
});