2

I am new to js and trying to sort an array of objects by two fields - starting with the first property, and then by the second property. Both properties are numbers.

The data is:

var homes = [{
 "h_id": "3",
 "minimumorder": "12",
 "price": "17"
 }, {
 "h_id": "4",
 "minimumorder": "1",
 "price": "20"
}, {
 "h_id": "5",
 "minimumorder": "1",
 "price": "18.10"
}

There are more objects in the array, this is a simplified example. The below code ALMOST gets me there, but for the minimumorder property it puts 12 after 1 instead of after 6:

cmp = function(a, b) {
 parseFloat(a);
 parseFloat(b);
 if (a > b) return +1;
 if (a < b) return -1;
 return 0;
}
homes.sort(function(a, b) { 
 return cmp(a.minimumorder,b.minimumorder) || cmp(a.price,b.price)
})

jsFiddle here.

Any help would be HUGELY appreciated, as I've been googling and tinkering for hours trying to figure this out.

Taymon
25.8k9 gold badges64 silver badges84 bronze badges
asked Jul 12, 2013 at 21:11
1
  • || cmp(a.price,b.price) is an elegant fallback when minimumorder returns 0. Nice Commented Nov 25, 2018 at 6:34

2 Answers 2

4

You need to reassign the parsed value back to a and b:

a = parseFloat(a);
b = parseFloat(b);

Otherwise it ends up comparing strings, and 12 occurs after 1 lexically, just like the word at comes after a in the dictionary.

Updated fiddle.

answered Jul 12, 2013 at 21:13
0
0

Well,

You should use a code like this:

function sortHomes(homes)
{
 var temp_homes = new Array();
 var new_homes = new Array();
 for(var i = 0; i < homes.length; i++) temp_homes[i] = homes[i];
 var maximum = 0, minimum;
 for(i = 0; i < temp_homes.length; i++) maximum = Math.max(maximum, temp_homes.minimumorder);
 var min_price, j, k, indexes, price_indexes;
 for(i = 0; i < temp_homes.length; i++){
 minimum = maximum;
 for(j = 0; j < temp_homes.length; j++){
 minimum = Math.min(minimum, temp_homes[j].minimumorder);
 }
 indexes = getIndexes(temp_homes, minimum, "minimumorder");
 if(indexes.length == 1){
 new_homes.push(temp_homes[indexes[0]]);
 temp_homes[indexes[0]].minimumorder = maximum + 1;
 }
 else{
 for(j = 0; j < indexes.length; j++){
 min_price = maximum;
 for(k = 0; k < indexes.length; k++){
 min_price = Math.min(min_price, temp_homes[indexes[k]].price);
 }
 price_indexes = getIndexes(temp_homes, min_price, "price");
 for(k = 0; k < price_indexes.length; k++){
 new_homes.push(temp_homes[price_indexes[k]]);
 temp_homes[price_indexes[k]].price = maximum + 1;
 }
 }
 }
 }
}
function getIndexes(arr, el, name)
{
 var indexes = new Array();
 for(var i = 0; i < arr.length; i++) if(arr[i][name] == el) indexes.push(i);
 return indexes;
}

It should work. If it doesn't, please inform me about it.

Oh, and in order to sort homes, just use:

homes = sortHomes(homes);

answered Jul 12, 2013 at 21:43

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.