You could use a chained sorting approach by taking the delta of values until it reaches a value not equal to zero.
var data = [{ h_id: "3", city: "Dallas", state: "TX", zip: "75201", price: "162500" }, { h_id: "4", city: "Bevery Hills", state: "CA", zip: "90210", price: "319250" }, { h_id: "6", city: "Dallas", state: "TX", zip: "75000", price: "556699" }, { h_id: "5", city: "New York", state: "NY", zip: "00010", price: "962500" }];
data.sort(function (a, b) {
return a.city.localeCompare(b.city) || b.price - a.price;
});
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Or, using es6, simply:
data.sort((a, b) => a.city.localeCompare(b.city) || b.price - a.price);
Answer from Nina Scholz on Stack OverflowYou could use a chained sorting approach by taking the delta of values until it reaches a value not equal to zero.
var data = [{ h_id: "3", city: "Dallas", state: "TX", zip: "75201", price: "162500" }, { h_id: "4", city: "Bevery Hills", state: "CA", zip: "90210", price: "319250" }, { h_id: "6", city: "Dallas", state: "TX", zip: "75000", price: "556699" }, { h_id: "5", city: "New York", state: "NY", zip: "00010", price: "962500" }];
data.sort(function (a, b) {
return a.city.localeCompare(b.city) || b.price - a.price;
});
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Or, using es6, simply:
data.sort((a, b) => a.city.localeCompare(b.city) || b.price - a.price);
for a non-generic, simple solution to your exact problem:
homes.sort(
function(a, b) {
if (a.city === b.city) {
// Price is only important when cities are the same
return b.price - a.price;
}
return a.city > b.city ? 1 : -1;
});
Day 57: How Do You Sort an Array of Objects by Multiple Properties in JavaScript?
Javascript - Sort Array of objects by 2 Properties - Stack Overflow
javascript - Sort an array of objects by multiple properties - Stack Overflow
[Javascript] sort an array with multiple keys, breaking ties of previous key with next key
You could use a chained approach for a specified order of keys and their sort order.
The array is sorted by the properties
resHP, ascending andresFlow, descending.
It works with calculating the delta and this reflects the relation of the two objects. If the value is zero, then the two values are equal and the next delta is calculated and returned.
var array = [{ resVal: "25FA15", resFlow: 49, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 1.5 }, { resVal: "25FA2", resFlow: 52, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 2 }, { resVal: "45FA2", resFlow: 53, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }, { resVal: "35FA2", resFlow: 59, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }];
array.sort(function (a, b) {
return a.resHP - b.resHP || b.resFlow - a.resFlow;
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
The requirement is to sort ascending by resHP property and then for any ties, sort descending by resFlow property.
Now, Javascript's Array.prototype.sort function allows us to sort an array. It accepts one parameter, which is a "compareFunction". The compareFunction accepts two parameters, which are elements of the array to be compared, and it must return their relative position in the expected resultant array.
function compareFunction (itemA, itemB) {...}
compareFunction(a, b)returns a numeric value greater than zero ifbcomes beforeain the result.
compareFunction(a, b)returns a numeric value less than zero ifbcomes afterain the result.
compareFunction(a, b)returns zero ifaandbare considered equivalent in terms of their relative order while sorting the array. For example, while sorting[5, 3, 5]both 5's are considered equivalent, hence the array should return 0 whencompareFunction(5,5)is called.
For sorting strings, providing a compareFunction is not necessary. As per the specification, when compareFunction is not provided, each value in the array is converted to string, and then sorted. Here's an example:
console.log('["z", "ct", "a", "aa", "ab", "bc"].sort(): ', ["z", "ct", "a", "aa", "ab", "bc"].sort());
Common Mistakes:
Comparing numbers without compareFunction
Although compareFunction is optional by specification, if it is not provided while sorting numbers or other objects, it may result into incorrect results. Consider the example below:
console.log("[1, 2, 5, 3, 0, 20].sort(): ", [1, 2, 5, 3, 0, 20].sort());
Here 20 appears before 3 because each number is converted to string before comparison, and since "20" comes before "3" in dictionary (if there was such a dictionary) it appears above "3" in the result.
Returning boolean value from compareFunction instead of numeric value
This is my mistake in the original answer.
When you return a boolean value instead of a numeric one out of the compareFunction, the boolean value is cast into a number. Meaning true will become 1 and false will become 0, but you are not returning -1.
var array = [
{
compareThis: 1,
originalIndex: 1
},
{
compareThis: 2,
originalIndex: 2
},
{
compareThis: -1,
originalIndex: 3
},
{
compareThis: -2,
originalIndex: 4
}
];
console.log(array.sort((a, b) => a.compareThis > b.compareThis));
Here the result is the unsorted, same array because when 2 and -1 are compared, the comparison 2 > -1 returns false, which is converted to 0. But when compareFunction returns 0 it indicates that the order of the two elements shall remain unchanged. Hence the array doesn't get sorted.
The correct way to sort this array would be:
var array = [
{
compareThis: 1,
originalIndex: 1
},
{
compareThis: 2,
originalIndex: 2
},
{
compareThis: -1,
originalIndex: 3
},
{
compareThis: -2,
originalIndex: 4
}
];
console.log(array.sort((a, b) => a.compareThis - b.compareThis));
So with that, the correct way to solve the problem presented in the question would be:
var array = [{ resVal: "25FA15", resFlow: 49, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 1.5 },
{ resVal: "25FA2", resFlow: 52, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 2 },
{ resVal: "45FA2", resFlow: 53, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 },
{ resVal: "35FA2", resFlow: 59, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }];
// The requirement is to sort ascending by resHP property and then for any ties, sort descending by resFlow property.
/* array.sort(function(a, b) {
if (a.resHP > b.resHP) {
return 1;
} else if (a.resHP === b.resHP) {
if (a.resFlow > b.resFlow) {
return -1;
} else if (a.resFlow === b.resFlow) {
return 0;
} else {
return 1;
}
} else {
return -1;
}
}); */
// Simplified to the following as we are working with numbers.
array.sort(function sortByResHP(a, b) {
return (a.resHP - b.resHP) !== 0 ? (a.resHP - b.resHP) : (b.resFlow - a.resFlow);
});
console.log("Result: ", array);
Of course this can be further shortened as shown in the other answer. I am leaving the longer version of the compareFunction to make it easier to read.
Original (incorrect) answer
You could use Array#sort for this:
array = [{ resVal: "25FA15", resFlow: 49, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 1.5 },
{ resVal: "25FA2", resFlow: 52, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 2 },
{ resVal: "45FA2", resFlow: 53, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 },
{ resVal: "35FA2", resFlow: 59, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }]
array.sort(function(d1,d2) {
if(d1.resHP == d2.resHP) {
return d1.resFlow < d2.resFlow;
} else {
return d1.resHP > d2.resHP;
}
});
console.log(array);
(Updated) Here's the answer of question you mentioned in comment.
a.sort(function(a, b) {
if (a.dnf != b.dnf) {
return a.dnf ? 1 : -1;
}
if (!(a.dnf && b.dnf) && a.isCut != b.isCut) {
return a.isCut ? 1 : -1;
}
if (a.score != b.score) {
return b.score - a.score; // descending
}
return b.id - a.id; // descending
});
Result:
[
{"id":4,"score":4,"isCut":false,"dnf":false}, // the rest: order by score, id
{"id":3,"score":3,"isCut":false,"dnf":false}, //
{"id":2,"score":2,"isCut":false,"dnf":false}, //
{"id":1,"score":1,"isCut":false,"dnf":false}, //
{"id":10,"score":0,"isCut":false,"dnf":false}, //
{"id":11,"score":-1,"isCut":false,"dnf":false}, //
{"id":13,"score":-3,"isCut":false,"dnf":false}, //
{"id":14,"score":-4,"isCut":false,"dnf":false}, //
{"id":15,"score":-5,"isCut":false,"dnf":false}, //
{"id":16,"score":10,"isCut":true,"dnf":false}, // isCut: order by score, id
{"id":9,"score":9,"isCut":true,"dnf":false}, //
{"id":8,"score":8,"isCut":true,"dnf":false}, //
{"id":7,"score":7,"isCut":true,"dnf":false}, //
{"id":6,"score":6,"isCut":true,"dnf":false}, //
{"id":5,"score":5,"isCut":true,"dnf":true}, // dnf: order by score, id
{"id":12,"score":-2,"isCut":false,"dnf":true} //
]
Use comparator function from Array
you can check answers here : Sort array of objects by string property value in JavaScript
I have an array of objects with multiple properties:
eg:
```
[
{
name: "b",
number: 1
},
{
name: "a",
number: 2
},
{
name: "b",
number: 2
}
]```
assume i want to sort by \[number, name\] descending, means that I want to sort by number in descending order first, which gives
```
[
{
name: "a",
number: 2
},
{
name: "b",
number: 2
},
{
name: "b",
number: 1
},
]```
then i resolve ties with the SAME number with descending order of name, which gives
```
[
{
name: "b",
number: 2
},
{
name: "a",
number: 2
},
{
name: "b",
number: 1
},
]```