Reputation: 452
I have an array of objects like this:-
var arr = [ {total : 20, name: David},
{total : 10, name: Joe},
{total : 15, name: Tracy},
{total : 20, name: Joel},
{total : 15, name: Michael},
{total : 10, name: Arnold},
{total : 15, name: Paul},
]
I need to sort them first by total and then if the total of two are the same I need to sort them by name
My expected outcome after sort should be as follows:
var arr = [ {total : 20, name: David},
{total : 20, name: Joel},
{total : 15, name: Michael},
{total : 15, name: Paul},
{total : 15, name: Tracy},
{total : 10, name: Arnold},
{total : 10, name: Joe},
]
Can anyone tell me how to sort it using Array.sort()?
Upvotes: 3
Views: 7532
Reputation: 421
easy and understandable:
var data = [
{total : '20', name: 'David'},
{total : '10', name: 'Joe'},
{total : '15', name: 'Tracy'},
{total : '20', name: 'Joel'},
{total : '15', name: 'Michael'},
{total : '10', name: 'Arnold'},
{total : '15', name: 'Paul'},
]
data.sort(compareMultiple(['name', '-total']));
function compareMultiple (criteria) {
return function (a, b) {
for (let key of criteria) {
var order = key.includes('-') ? -1 : 1;
if (!a[key]) return -order;
if (!b[key]) return order;
if (!a[key] && ![key]) return 0;
if (a[key] > b[key]) return order;
if (a[key] < b[key]) return -order;
}
return 0;
};
}
Upvotes: 0
Reputation: 386680
You could chain the sort criteria with logical OR and use a delta for total
and String#localeCompare
for name
.
// Sort by total then name.
var array = [
{total: 20, name: 'David'},
{total: 10, name: 'Joe'},
{total: 15, name: 'Tracy'},
{total: 20, name: 'Joel'},
{total: 15, name: 'Michael'},
{total: 10, name: 'Arnold'},
{total: 15, name: 'Paul'}
];
array.sort(function (a, b) {
return b.total - a.total || a.name.localeCompare(b.name);
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 6
Reputation: 1055
var array = [{ total: 20, name: 'David' }, { total: 10, name: 'Joe' }, { total: 15, name: 'Tracy' }, { total: 20, name: 'Joel' }, { total: 15, name: 'Michael' }, { total: 10, name: 'Arnold' }, { total: 15, name: 'Paul' }];
array.sort(function(a, b) {
return totalCompare(a, b) || a.name.localeCompare(b.name);
});
function totalCompare(a, b) {
if (a.total === b.total) {
return 0;
}
return b.total - a.total;
}
console.log(array);
Upvotes: 1
Reputation: 4578
You can provide a sortObject
which contains the keys with their respective directions (in order of sorting):
const sortObject = {
total: -1, // Descending
name: 1, // Ascending
};
You can then use that object to loop through the array for sorting:
const arr = [
{ total: 20, name: 'David' },
{ total: 10, name: 'Joe' },
{ total: 15, name: 'Tracy' },
{ total: 20, name: 'Joel' },
{ total: 15, name: 'Michael' },
{ total: 10, name: 'Arnold' },
{ total: 15, name: 'Paul' },
];
// Enter keys by sort order. Key values are -1 for descending and 1 for ascending.
const sortObject = {
total: -1,
name: 1,
};
// Get the keys of sortObject.
const sortKeys = Object.keys(sortObject);
const sortedArray = arr.sort((a, b) => {
let sorted = 0;
let index = 0;
// Loop until sorted or until the sort keys have been processed.
while (sorted === 0 && index < sortKeys.length) {
const key = sortKeys[index];
const sortDirection = sortObject[key];
if (a[key] === b[key]) { // If the values are the same, do not change positions.
sorted = 0;
} else { // Switch positions if necessary. If b[key] > a[key], multiply by -1 to reverse directions.
sorted = a[key] > b[key] ? sortDirection : -1 * sortDirection;
}
index++;
}
return sorted;
});
console.log(sortedArray);
Upvotes: 0
Reputation: 22564
You can sort your array using custom sort function. Please use the link to know more about the sort function.
You can use the below code to sort.
arr.sort((a,b) => (b.total === a.total ? (a.name > b.name) : b.total - a.total));
Here is the solution of your problem.
var arr = [ {total : 20, name: 'David'},
{total : 10, name: 'Joe'},
{total : 15, name: 'Tracy'},
{total : 20, name: 'Joel'},
{total : 15, name: 'Michael'},
{total : 10, name: 'Arnold'},
{total : 15, name: 'Paul'}];
arr.sort((a,b) => (b.total === a.total ? (a.name > b.name) : b.total - a.total));
console.log(arr);
Upvotes: 0
Reputation: 89
The sort method can be conveniently used with function expressions (and closures):
This article talks about the two ways to use Array.sort()
One of them being the exact explanation you are looking for--passing a compareFunction
to the method parameters of sort()
This will allow you to specify any function you want (within reason) to define the sort order.
Ex:
arrayname.sort(function(a, b){
return b-a;
});
Would return the sorted array in descending order
Upvotes: 0
Reputation: 881
Using sort() method
var data = [
{total : '20', name: 'David'},
{total : '10', name: 'Joe'},
{total : '15', name: 'Tracy'},
{total : '20', name: 'Joel'},
{total : '15', name: 'Michael'},
{total : '10', name: 'Arnold'},
{total : '15', name: 'Paul'},
]
data.sort(function (x, y) {
var n = x.total - y.total;
if (n != 0) {
return n;
}
return x.name - y.name;
});
var i;
for (i = 0; i < data.length; i++) {
document.write("<p>total:" + data[i].total +" name:" + data[i].name + "</p>");
}
here runnig code https://jsfiddle.net/bhupeshkushwaha/jv3mng0y/
Upvotes: 0
Reputation: 759
<!DOCTYPE html>
<html>
<body>
<p>Click the button to sort the array.</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits;
function myFunction() {
fruits.sort();
document.getElementById("demo").innerHTML = fruits;
}
</script>
</body>
</html>
just like this....
Upvotes: 0
Reputation: 66
use Array.sort(callback), the callback func has two parameter a、b are item in arrary, and return a int value if <0 a lt b else if = 0 a eq b else > 0 a gt b
arr.sort(function(a,b){
return a.total == b.total ? (a.name > b.name ? 1: -1) : a.total-b.total;
});
Upvotes: 2