I've got the following objects using AJAX and stored them in an array:
var homes = [
{
"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": "5",
"city": "New York",
"state": "NY",
"zip": "00010",
"price": "962500"
}
];
How do I create a function to sort the objects by the price
property in ascending or descending order using JavaScript only?
This question is related to
javascript
arrays
sorting
You want to sort it in Javascript, right? What you want is the sort()
function. In this case you need to write a comparator function and pass it to sort()
, so something like this:
function comparator(a, b) {
return parseInt(a["price"], 10) - parseInt(b["price"], 10);
}
var json = { "homes": [ /* your previous data */ ] };
console.log(json["homes"].sort(comparator));
Your comparator takes one of each of the nested hashes inside the array and decides which one is higher by checking the "price" field.
Hi after reading this article, I made a sortComparator for my needs, with the functionality to compare more than one json attributes, and i want to share it with you.
This solution compares only strings in ascending order, but the solution can be easy extended for each attribute to support: reverse ordering, other data types, to use locale, casting etc
var homes = [{
"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": "5",
"city": "New York",
"state": "NY",
"zip": "00010",
"price": "962500"
}];
// comp = array of attributes to sort
// comp = ['attr1', 'attr2', 'attr3', ...]
function sortComparator(a, b, comp) {
// Compare the values of the first attribute
if (a[comp[0]] === b[comp[0]]) {
// if EQ proceed with the next attributes
if (comp.length > 1) {
return sortComparator(a, b, comp.slice(1));
} else {
// if no more attributes then return EQ
return 0;
}
} else {
// return less or great
return (a[comp[0]] < b[comp[0]] ? -1 : 1)
}
}
// Sort array homes
homes.sort(function(a, b) {
return sortComparator(a, b, ['state', 'city', 'zip']);
});
// display the array
homes.forEach(function(home) {
console.log(home.h_id, home.city, home.state, home.zip, home.price);
});
and the result is
$ node sort
4 Bevery Hills CA 90210 319250
5 New York NY 00010 962500
3 Dallas TX 75201 162500
and another sort
homes.sort(function(a, b) {
return sortComparator(a, b, ['city', 'zip']);
});
with result
$ node sort
4 Bevery Hills CA 90210 319250
3 Dallas TX 75201 162500
5 New York NY 00010 962500
A simple code :
var homes = [_x000D_
{_x000D_
"h_id": "3",_x000D_
"city": "Dallas",_x000D_
"state": "TX",_x000D_
"zip": "75201",_x000D_
"price": "162500"_x000D_
}, {_x000D_
"h_id": "4",_x000D_
"city": "Bevery Hills",_x000D_
"state": "CA",_x000D_
"zip": "90210",_x000D_
"price": "319250"_x000D_
}, {_x000D_
"h_id": "5",_x000D_
"city": "New York",_x000D_
"state": "NY",_x000D_
"zip": "00010",_x000D_
"price": "962500"_x000D_
}_x000D_
];_x000D_
_x000D_
let sortByPrice = homes.sort(function (a, b) _x000D_
{_x000D_
return parseFloat(b.price) - parseFloat(a.price);_x000D_
});_x000D_
_x000D_
for (var i=0; i<sortByPrice.length; i++)_x000D_
{_x000D_
document.write(sortByPrice[i].h_id+' '+sortByPrice[i].city+' '_x000D_
+sortByPrice[i].state+' '_x000D_
+sortByPrice[i].zip+' '+sortByPrice[i].price);_x000D_
document.write("<br>");_x000D_
}
_x000D_
You can use string1.localeCompare(string2) for string comparison
this.myArray.sort((a,b) => {
return a.stringProp.localeCompare(b.stringProp);
});
Note that localCompare
is case insensitive
If you use Underscore.js, try sortBy:
// price is of an integer type
_.sortBy(homes, "price");
// price is of a string type
_.sortBy(homes, function(home) {return parseInt(home.price);});
Here is a slightly modified version of elegant implementation from the book "JavaScript: The Good Parts".
NOTE: This version of by
is stable. It preserves the order of the first sort while performing the next chained sort.
I have added isAscending
parameter to it. Also converted it to ES6
standards and "newer" good parts as recommended by the author.
You can sort ascending as well as descending and chain sort by multiple properties.
const by = function (name, minor, isAscending=true) {_x000D_
const reverseMutliplier = isAscending ? 1 : -1;_x000D_
return function (o, p) {_x000D_
let a, b;_x000D_
let result;_x000D_
if (o && p && typeof o === "object" && typeof p === "object") {_x000D_
a = o[name];_x000D_
b = p[name];_x000D_
if (a === b) {_x000D_
return typeof minor === 'function' ? minor(o, p) : 0;_x000D_
}_x000D_
if (typeof a === typeof b) {_x000D_
result = a < b ? -1 : 1;_x000D_
} else {_x000D_
result = typeof a < typeof b ? -1 : 1;_x000D_
}_x000D_
return result * reverseMutliplier;_x000D_
} else {_x000D_
throw {_x000D_
name: "Error",_x000D_
message: "Expected an object when sorting by " + name_x000D_
};_x000D_
}_x000D_
};_x000D_
};_x000D_
_x000D_
let s = [_x000D_
{first: 'Joe', last: 'Besser'},_x000D_
{first: 'Moe', last: 'Howard'},_x000D_
{first: 'Joe', last: 'DeRita'},_x000D_
{first: 'Shemp', last: 'Howard'},_x000D_
{first: 'Larry', last: 'Fine'},_x000D_
{first: 'Curly', last: 'Howard'}_x000D_
];_x000D_
_x000D_
// Sort by: first ascending, last ascending_x000D_
s.sort(by("first", by("last"))); _x000D_
console.log("Sort by: first ascending, last ascending: ", s); // "[_x000D_
// {"first":"Curly","last":"Howard"},_x000D_
// {"first":"Joe","last":"Besser"}, <======_x000D_
// {"first":"Joe","last":"DeRita"}, <======_x000D_
// {"first":"Larry","last":"Fine"},_x000D_
// {"first":"Moe","last":"Howard"},_x000D_
// {"first":"Shemp","last":"Howard"}_x000D_
// ]_x000D_
_x000D_
// Sort by: first ascending, last descending_x000D_
s.sort(by("first", by("last", 0, false))); _x000D_
console.log("sort by: first ascending, last descending: ", s); // "[_x000D_
// {"first":"Curly","last":"Howard"},_x000D_
// {"first":"Joe","last":"DeRita"}, <========_x000D_
// {"first":"Joe","last":"Besser"}, <========_x000D_
// {"first":"Larry","last":"Fine"},_x000D_
// {"first":"Moe","last":"Howard"},_x000D_
// {"first":"Shemp","last":"Howard"}_x000D_
// ]
_x000D_
I recently wrote a universal function to manage this for you if you want to use it.
/**
* Sorts an object into an order
*
* @require jQuery
*
* @param object Our JSON object to sort
* @param type Only alphabetical at the moment
* @param identifier The array or object key to sort by
* @param order Ascending or Descending
*
* @returns Array
*/
function sortItems(object, type, identifier, order){
var returnedArray = [];
var emptiesArray = []; // An array for all of our empty cans
// Convert the given object to an array
$.each(object, function(key, object){
// Store all of our empty cans in their own array
// Store all other objects in our returned array
object[identifier] == null ? emptiesArray.push(object) : returnedArray.push(object);
});
// Sort the array based on the type given
switch(type){
case 'alphabetical':
returnedArray.sort(function(a, b){
return(a[identifier] == b[identifier]) ? 0 : (
// Sort ascending or descending based on order given
order == 'asc' ? a[identifier] > b[identifier] : a[identifier] < b[identifier]
) ? 1 : -1;
});
break;
default:
}
// Return our sorted array along with the empties at the bottom depending on sort order
return order == 'asc' ? returnedArray.concat(emptiesArray) : emptiesArray.concat(returnedArray);
}
function compareValues(key, order = 'asc') {
return function innerSort(a, b) {
if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
// property doesn't exist on either object
return 0;
}
const varA = (typeof a[key] === 'string')
? a[key].toUpperCase() : a[key];
const varB = (typeof b[key] === 'string')
? b[key].toUpperCase() : b[key];
let comparison = 0;
if (varA > varB) {
comparison = 1;
} else if (varA < varB) {
comparison = -1;
}
return (
(order === 'desc') ? (comparison * -1) : comparison
);
};
}
http://yazilimsozluk.com/sort-array-in-javascript-by-asc-or-desc
This could have been achieved through a simple one line valueof() sort function. Run code snippet below to see demo.
var homes = [_x000D_
{_x000D_
"h_id": "3",_x000D_
"city": "Dallas",_x000D_
"state": "TX",_x000D_
"zip": "75201",_x000D_
"price": "162500"_x000D_
}, {_x000D_
"h_id": "4",_x000D_
"city": "Bevery Hills",_x000D_
"state": "CA",_x000D_
"zip": "90210",_x000D_
"price": "319250"_x000D_
}, {_x000D_
"h_id": "5",_x000D_
"city": "New York",_x000D_
"state": "NY",_x000D_
"zip": "00010",_x000D_
"price": "962500"_x000D_
}_x000D_
];_x000D_
_x000D_
console.log("To sort descending/highest first, use operator '<'");_x000D_
_x000D_
homes.sort(function(a,b) { return a.price.valueOf() < b.price.valueOf();});_x000D_
_x000D_
console.log(homes);_x000D_
_x000D_
console.log("To sort ascending/lowest first, use operator '>'");_x000D_
_x000D_
homes.sort(function(a,b) { return a.price.valueOf() > b.price.valueOf();});_x000D_
_x000D_
console.log(homes);
_x000D_
I also worked with some kind of rating and multiple fields sort:
arr = [
{type:'C', note:834},
{type:'D', note:732},
{type:'D', note:008},
{type:'F', note:474},
{type:'P', note:283},
{type:'P', note:165},
{type:'X', note:173},
{type:'Z', note:239},
];
arr.sort(function(a,b){
var _a = ((a.type==='C')?'0':(a.type==='P')?'1':'2');
_a += (a.type.localeCompare(b.type)===-1)?'0':'1';
_a += (a.note>b.note)?'1':'0';
var _b = ((b.type==='C')?'0':(b.type==='P')?'1':'2');
_b += (b.type.localeCompare(a.type)===-1)?'0':'1';
_b += (b.note>a.note)?'1':'0';
return parseInt(_a) - parseInt(_b);
});
Result
[
{"type":"C","note":834},
{"type":"P","note":165},
{"type":"P","note":283},
{"type":"D","note":8},
{"type":"D","note":732},
{"type":"F","note":474},
{"type":"X","note":173},
{"type":"Z","note":239}
]
Here is a culmination of all answers above.
Fiddle validation: http://jsfiddle.net/bobberino/4qqk3/
var sortOn = function (arr, prop, reverse, numeric) {
// Ensure there's a property
if (!prop || !arr) {
return arr
}
// Set up sort function
var sort_by = function (field, rev, primer) {
// Return the required a,b function
return function (a, b) {
// Reset a, b to the field
a = primer(a[field]), b = primer(b[field]);
// Do actual sorting, reverse as needed
return ((a < b) ? -1 : ((a > b) ? 1 : 0)) * (rev ? -1 : 1);
}
}
// Distinguish between numeric and string to prevent 100's from coming before smaller
// e.g.
// 1
// 20
// 3
// 4000
// 50
if (numeric) {
// Do sort "in place" with sort_by function
arr.sort(sort_by(prop, reverse, function (a) {
// - Force value to a string.
// - Replace any non numeric characters.
// - Parse as float to allow 0.02 values.
return parseFloat(String(a).replace(/[^0-9.-]+/g, ''));
}));
} else {
// Do sort "in place" with sort_by function
arr.sort(sort_by(prop, reverse, function (a) {
// - Force value to string.
return String(a).toUpperCase();
}));
}
}
With ECMAScript 6 StoBor's answer can be done even more concise:
homes.sort((a, b) => a.price - b.price)
For a normal array of elements values only:
function sortArrayOfElements(arrayToSort) {
function compareElements(a, b) {
if (a < b)
return -1;
if (a > b)
return 1;
return 0;
}
return arrayToSort.sort(compareElements);
}
e.g. 1:
var array1 = [1,2,545,676,64,2,24]
output : [1, 2, 2, 24, 64, 545, 676]
var array2 = ["v","a",545,676,64,2,"24"]
output: ["a", "v", 2, "24", 64, 545, 676]
For an array of objects:
function sortArrayOfObjects(arrayToSort, key) {
function compareObjects(a, b) {
if (a[key] < b[key])
return -1;
if (a[key] > b[key])
return 1;
return 0;
}
return arrayToSort.sort(compareObjects);
}
e.g. 1: var array1= [{"name": "User4", "value": 4},{"name": "User3", "value": 3},{"name": "User2", "value": 2}]
output : [{"name": "User2", "value": 2},{"name": "User3", "value": 3},{"name": "User4", "value": 4}]
I'm little late for the party but below is my logic for sorting.
function getSortedData(data, prop, isAsc) {
return data.sort((a, b) => {
return (a[prop] < b[prop] ? -1 : 1) * (isAsc ? 1 : -1)
});
}
Create a function and sort based on the input using below code
var homes = [{
"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": "5",
"city": "New York",
"state": "NY",
"zip": "00010",
"price": "962500"
}];
function sortList(list,order){
if(order=="ASC"){
return list.sort((a,b)=>{
return parseFloat(a.price) - parseFloat(b.price);
})
}
else{
return list.sort((a,b)=>{
return parseFloat(b.price) - parseFloat(a.price);
});
}
}
sortList(homes,'DESC');
console.log(homes);
Descending order of price:
homes.sort((x,y) => {return y.price - x.price})
Ascending order of price:
homes.sort((x,y) => {return x.price - y.price})
You can use the JavaScript sort
method with a callback function:
function compareASC(homeA, homeB)
{
return parseFloat(homeA.price) - parseFloat(homeB.price);
}
function compareDESC(homeA, homeB)
{
return parseFloat(homeB.price) - parseFloat(homeA.price);
}
// Sort ASC
homes.sort(compareASC);
// Sort DESC
homes.sort(compareDESC);
For sorting a array you must define a comparator function. This function always be different on your desired sorting pattern or order(i.e. ascending or descending).
Let create some functions that sort an array ascending or descending and that contains object or string or numeric values.
function sorterAscending(a,b) {
return a-b;
}
function sorterDescending(a,b) {
return b-a;
}
function sorterPriceAsc(a,b) {
return parseInt(a['price']) - parseInt(b['price']);
}
function sorterPriceDes(a,b) {
return parseInt(b['price']) - parseInt(b['price']);
}
Sort numbers (alphabetically and ascending):
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
Sort numbers (alphabetically and descending):
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
fruits.reverse();
Sort numbers (numerically and ascending):
var points = [40,100,1,5,25,10];
points.sort(sorterAscending());
Sort numbers (numerically and descending):
var points = [40,100,1,5,25,10];
points.sort(sorterDescending());
As above use sorterPriceAsc and sorterPriceDes method with your array with desired key.
homes.sort(sorterPriceAsc()) or homes.sort(sorterPriceDes())
for string sorting in case some one needs it,
const dataArr = {_x000D_
_x000D_
"hello": [{_x000D_
"id": 114,_x000D_
"keyword": "zzzzzz",_x000D_
"region": "Sri Lanka",_x000D_
"supportGroup": "administrators",_x000D_
"category": "Category2"_x000D_
}, {_x000D_
"id": 115,_x000D_
"keyword": "aaaaa",_x000D_
"region": "Japan",_x000D_
"supportGroup": "developers",_x000D_
"category": "Category2"_x000D_
}]_x000D_
_x000D_
};_x000D_
const sortArray = dataArr['hello'];_x000D_
_x000D_
console.log(sortArray.sort((a, b) => {_x000D_
if (a.region < b.region)_x000D_
return -1;_x000D_
if (a.region > b.region)_x000D_
return 1;_x000D_
return 0;_x000D_
}));
_x000D_
If you have an ES6 compliant browser you can use:
The difference between ascending and descending sort order is the sign of the value returned by your compare function:
var ascending = homes.sort((a, b) => Number(a.price) - Number(b.price));
var descending = homes.sort((a, b) => Number(b.price) - Number(a.price));
Here's a working code snippet:
var homes = [{_x000D_
"h_id": "3",_x000D_
"city": "Dallas",_x000D_
"state": "TX",_x000D_
"zip": "75201",_x000D_
"price": "162500"_x000D_
}, {_x000D_
"h_id": "4",_x000D_
"city": "Bevery Hills",_x000D_
"state": "CA",_x000D_
"zip": "90210",_x000D_
"price": "319250"_x000D_
}, {_x000D_
"h_id": "5",_x000D_
"city": "New York",_x000D_
"state": "NY",_x000D_
"zip": "00010",_x000D_
"price": "962500"_x000D_
}];_x000D_
_x000D_
homes.sort((a, b) => Number(a.price) - Number(b.price));_x000D_
console.log("ascending", homes);_x000D_
_x000D_
homes.sort((a, b) => Number(b.price) - Number(a.price));_x000D_
console.log("descending", homes);
_x000D_
homes.sort(function(a, b){
var nameA=a.prices.toLowerCase(), nameB=b.prices.toLowerCase()
if (nameA < nameB) //sort string ascending
return -1
if (nameA > nameB)
return 1
return 0 //default return value (no sorting)
})
For sort on multiple array object field.
Enter your field name in arrprop
array like ["a","b","c"]
then pass in second parameter arrsource
actual source we want to sort.
function SortArrayobject(arrprop,arrsource){
arrprop.forEach(function(i){
arrsource.sort(function(a,b){
return ((a[i] < b[i]) ? -1 : ((a[i] > b[i]) ? 1 : 0));
});
});
return arrsource;
}
Here's a more flexible version, which allows you to create reusable sort functions, and sort by any field.
const sort_by = (field, reverse, primer) => {_x000D_
_x000D_
const key = primer ?_x000D_
function(x) {_x000D_
return primer(x[field])_x000D_
} :_x000D_
function(x) {_x000D_
return x[field]_x000D_
};_x000D_
_x000D_
reverse = !reverse ? 1 : -1;_x000D_
_x000D_
return function(a, b) {_x000D_
return a = key(a), b = key(b), reverse * ((a > b) - (b > a));_x000D_
}_x000D_
}_x000D_
_x000D_
_x000D_
//Now you can sort by any field at will..._x000D_
_x000D_
const homes=[{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:"5",city:"New York",state:"NY",zip:"00010",price:"962500"}];_x000D_
_x000D_
// Sort by price high to low_x000D_
console.log(homes.sort(sort_by('price', true, parseInt)));_x000D_
_x000D_
// Sort by city, case-insensitive, A-Z_x000D_
console.log(homes.sort(sort_by('city', false, (a) => a.toUpperCase()_x000D_
)));
_x000D_
While it is a bit of an overkill for just sorting a single array, this prototype function allows to sort Javascript arrays by any key, in ascending or descending order, including nested keys, using dot
syntax.
(function(){
var keyPaths = [];
var saveKeyPath = function(path) {
keyPaths.push({
sign: (path[0] === '+' || path[0] === '-')? parseInt(path.shift()+1) : 1,
path: path
});
};
var valueOf = function(object, path) {
var ptr = object;
for (var i=0,l=path.length; i<l; i++) ptr = ptr[path[i]];
return ptr;
};
var comparer = function(a, b) {
for (var i = 0, l = keyPaths.length; i < l; i++) {
aVal = valueOf(a, keyPaths[i].path);
bVal = valueOf(b, keyPaths[i].path);
if (aVal > bVal) return keyPaths[i].sign;
if (aVal < bVal) return -keyPaths[i].sign;
}
return 0;
};
Array.prototype.sortBy = function() {
keyPaths = [];
for (var i=0,l=arguments.length; i<l; i++) {
switch (typeof(arguments[i])) {
case "object": saveKeyPath(arguments[i]); break;
case "string": saveKeyPath(arguments[i].match(/[+-]|[^.]+/g)); break;
}
}
return this.sort(comparer);
};
})();
Usage:
var data = [
{ name: { first: 'Josh', last: 'Jones' }, age: 30 },
{ name: { first: 'Carlos', last: 'Jacques' }, age: 19 },
{ name: { first: 'Carlos', last: 'Dante' }, age: 23 },
{ name: { first: 'Tim', last: 'Marley' }, age: 9 },
{ name: { first: 'Courtney', last: 'Smith' }, age: 27 },
{ name: { first: 'Bob', last: 'Smith' }, age: 30 }
]
data.sortBy('age'); // "Tim Marley(9)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Bob Smith(30)"
Sorting by nested properties with dot-syntax or array-syntax:
data.sortBy('name.first'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy(['name', 'first']); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
Sorting by multiple keys:
data.sortBy('name.first', 'age'); // "Bob Smith(30)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy('name.first', '-age'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
You can fork the repo: https://github.com/eneko/Array.sortBy
I recommend GitHub: Array sortBy - a best implementation of sortBy
method which uses the Schwartzian transform
But for now we are going to try this approach Gist: sortBy-old.js.
Let's create a method to sort arrays being able to arrange objects by some property.
var sortBy = (function () {
var toString = Object.prototype.toString,
// default parser function
parse = function (x) { return x; },
// gets the item to be sorted
getItem = function (x) {
var isObject = x != null && typeof x === "object";
var isProp = isObject && this.prop in x;
return this.parser(isProp ? x[this.prop] : x);
};
/**
* Sorts an array of elements.
*
* @param {Array} array: the collection to sort
* @param {Object} cfg: the configuration options
* @property {String} cfg.prop: property name (if it is an Array of objects)
* @property {Boolean} cfg.desc: determines whether the sort is descending
* @property {Function} cfg.parser: function to parse the items to expected type
* @return {Array}
*/
return function sortby (array, cfg) {
if (!(array instanceof Array && array.length)) return [];
if (toString.call(cfg) !== "[object Object]") cfg = {};
if (typeof cfg.parser !== "function") cfg.parser = parse;
cfg.desc = !!cfg.desc ? -1 : 1;
return array.sort(function (a, b) {
a = getItem.call(cfg, a);
b = getItem.call(cfg, b);
return cfg.desc * (a < b ? -1 : +(a > b));
});
};
}());
var data = [
{date: "2011-11-14T16:30:43Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T17:22:59Z", quantity: 2, total: 90, tip: 0, type: "Tab"},
{date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
{date: "2011-11-14T16:53:41Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T16:48:46Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0, type: "cash"},
{date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"},
{date: "2011-11-14T16:58:03Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
{date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
{date: "2011-11-14T17:07:21Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "Cash"}
];
Arrange the array, by "date"
as String
// sort by @date (ascending)
sortBy(data, { prop: "date" });
// expected: first element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }
// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}
If you want to ignore case sensitive, set the parser
callback:
// sort by @type (ascending) IGNORING case-sensitive
sortBy(data, {
prop: "type",
parser: (t) => t.toUpperCase()
});
// expected: first element
// { date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "Cash" }
// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa" }
If you want to convert the "date"
field as Date
type:
// sort by @date (descending) AS Date object
sortBy(data, {
prop: "date",
desc: true,
parser: (d) => new Date(d)
});
// expected: first element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}
// expected: last element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }
Here you can play with the code: jsbin.com/lesebi
Thanks to @Ozesh by his feedback, the issue related to properties with falsy values was fixed.
Use lodash.sortBy, (instructions using commonjs, you can also just put the script include-tag for the cdn at the top of your html)
var sortBy = require('lodash.sortby');
// or
sortBy = require('lodash').sortBy;
Descending order
var descendingOrder = sortBy( homes, 'price' ).reverse();
Ascending order
var ascendingOrder = sortBy( homes, 'price' );
You will need two function
function desc(a, b) {
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}
function asc(a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
Then you can apply this to any object property:
data.sort((a, b) => desc(parseFloat(a.price), parseFloat(b.price)));
let data = [_x000D_
{label: "one", value:10},_x000D_
{label: "two", value:5},_x000D_
{label: "three", value:1},_x000D_
];_x000D_
_x000D_
// sort functions_x000D_
function desc(a, b) {_x000D_
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;_x000D_
}_x000D_
_x000D_
function asc(a, b) {_x000D_
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;_x000D_
}_x000D_
_x000D_
// DESC_x000D_
data.sort((a, b) => desc(a.value, b.value));_x000D_
_x000D_
document.body.insertAdjacentHTML(_x000D_
'beforeend', _x000D_
'<strong>DESCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'_x000D_
);_x000D_
_x000D_
// ASC_x000D_
data.sort((a, b) => asc(a.value, b.value));_x000D_
_x000D_
document.body.insertAdjacentHTML(_x000D_
'beforeend', _x000D_
'<strong>ASCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'_x000D_
);
_x000D_
While I am aware that the OP wanted to sort an array of numbers, this question has been marked as the answer for similar questions regarding strings. To that fact, the above answers do not consider sorting an array of text where casing is important. Most answers take the string values and convert them to uppercase/lowercase and then sort one way or another. The requirements that I adhere to are simple:
What I expect is [ A, a, B, b, C, c ]
but the answers above return A, B, C, a, b, c
. I actually scratched my head on this for longer than I wanted (which is why I am posting this in hopes that it will help at least one other person). While two users mention the localeCompare
function in the comments for the marked answer, I didn't see that until after I stumbled upon the function while searching around. After reading the String.prototype.localeCompare() documentation I was able to come up with this:
var values = [ "Delta", "charlie", "delta", "Charlie", "Bravo", "alpha", "Alpha", "bravo" ];
var sorted = values.sort((a, b) => a.localeCompare(b, undefined, { caseFirst: "upper" }));
// Result: [ "Alpha", "alpha", "Bravo", "bravo", "Charlie", "charlie", "Delta", "delta" ]
This tells the function to sort uppercase values before lowercase values. The second parameter in the localeCompare
function is to define the locale but if you leave it as undefined
it automatically figures out the locale for you.
This works the same for sorting an array of objects as well:
var values = [
{ id: 6, title: "Delta" },
{ id: 2, title: "charlie" },
{ id: 3, title: "delta" },
{ id: 1, title: "Charlie" },
{ id: 8, title: "Bravo" },
{ id: 5, title: "alpha" },
{ id: 4, title: "Alpha" },
{ id: 7, title: "bravo" }
];
var sorted = values
.sort((a, b) => a.title.localeCompare(b.title, undefined, { caseFirst: "upper" }));
To sort it you need to create a comparator function taking two arguments. Then call the sort function with that comparator function as follows:
// a and b are object elements of your array
function mycomparator(a,b) {
return parseInt(a.price, 10) - parseInt(b.price, 10);
}
homes.sort(mycomparator);
If you want to sort ascending switch the expressions on each side of the minus sign.
Source: Stackoverflow.com