I got an array (see below for one object in the array) that I need to sort by firstname using JavaScript. How can I do it?
var user = { bio: null, email: "", firstname: "Anna", id: 318, lastAvatar: null, lastMessage: null, lastname: "Nickson", nickname: "anny" }; 023 Answers
Shortest possible code with ES6!
users.sort((a, b) => a.firstname.localeCompare(b.firstname)) String.prototype.localeCompare() basic support is universal!
6Suppose you have an array users. You may use users.sort and pass a function that takes two arguments and compare them (comparator)
It should return
- something negative if first argument is less than second (should be placed before the second in resulting array)
- something positive if first argument is greater (should be placed after second one)
- 0 if those two elements are equal.
In our case if two elements are a and b we want to compare a.firstname and b.firstname
Example:
users.sort(function(a, b){ if(a.firstname < b.firstname) { return -1; } if(a.firstname > b.firstname) { return 1; } return 0; }) This code is going to work with any type.
Note that in "real life"™ you often want to ignore case, correctly sort diacritics, weird symbols like ß, etc. when you compare strings, so you may want to use localeCompare. See other answers for clarity.
Something like this:
array.sort(function(a, b){ var nameA = a.name.toLowerCase(), nameB = b.name.toLowerCase(); if (nameA < nameB) //sort string ascending return -1; if (nameA > nameB) return 1; return 0; //default return value (no sorting) }); 7If compared strings contain unicode characters you can use localeCompare function of String class like the following:
users.sort(function(a,b){ return a.firstname.localeCompare(b.firstname); }) 8Nice little ES6 one liner:
users.sort((a, b) => a.firstname !== b.firstname ? a.firstname < b.firstname ? -1 : 1 : 0); 3We can use localeCompare but need to check the keys as well for falsey values
The code below will not work if one entry has missing lname.
obj.sort((a, b) => a.lname.localeCompare(b.lname)) So we need to check for falsey value like below
let obj=[ {name:'john',lname:'doe',address:'Alaska'}, {name:'tom',lname:'hopes',address:'California'}, {name:'harry',address:'Texas'} ] let field='lname'; console.log(obj.sort((a, b) => (a[field] || "").toString().localeCompare((b[field] || "").toString())));OR
we can use lodash , its very simple. It will detect the returned values i.e whether number or string and do sorting accordingly .
import sortBy from 'lodash/sortBy'; sortBy(obj,'name') 0underscorejs offers the very nice _.sortBy function:
_.sortBy([{a:1},{a:3},{a:2}], "a") or you can use a custom sort function:
_.sortBy([{a:"b"},{a:"c"},{a:"a"}], function(i) {return i.a.toLowerCase()}) 1In case we are sorting names or something with special characters, like ñ or áéíóú (commons in Spanish) we could use the params locales (es for spanish in this case ) and options like this:
let user = [{'firstname': 'Az'},{'firstname': 'Áb'},{'firstname':'ay'},{'firstname': 'Ña'},{'firstname': 'Nz'},{'firstname': 'ny'}]; user.sort((a, b) => a.firstname.localeCompare(b.firstname, 'es', {sensitivity: 'base'})) console.log(user)The oficial locale options could be found here in iana, es (spanish), de (German), fr (French). About sensitivity base means:
Only strings that differ in base letters compare as unequal. Examples: a ≠ b, a = á, a = A.
A more compact notation:
user.sort(function(a, b){ return a.firstname === b.firstname ? 0 : a.firstname < b.firstname ? -1 : 1; }) 2I'm surprised no one mentioned Collators. You shouldn't use localeCompare unless you have to as it has significantly worse performance
const collator = new Intl.Collator('zh-CN'); // Chinese Simplified for example function sortAsc(a, b) { if (typeof a === 'string' && typeof b === 'string') { return collator.compare(b, a) } return b - a; } function sortDesc(a, b) { if (typeof a === 'string' && typeof b === 'string') { return collator.compare(a, b); } return a - b; } 0Basically you can sort arrays with method sort, but if you want to sort objects then you have to pass function to sort method of array, so I will give you an example using your array
user = [{ bio: "<null>", email: "", firstname: 'Anna', id: 318, "last_avatar": "<null>", "last_message": "<null>", lastname: 'Nickson', nickname: 'anny' }, { bio: "<null>", email: "", firstname: 'Senad', id: 318, "last_avatar": "<null>", "last_message": "<null>", lastname: 'Nickson', nickname: 'anny' }, { bio: "<null>", email: "", firstname: 'Muhamed', id: 318, "last_avatar": "<null>", "last_message": "<null>", lastname: 'Nickson', nickname: 'anny' }]; var ar = user.sort(function(a, b) { var nA = a.firstname.toLowerCase(); var nB = b.firstname.toLowerCase(); if(nA < nB) return -1; else if(nA > nB) return 1; return 0; }); 4try
users.sort((a,b)=> (a.firstname>b.firstname)*2-1) var users = [ { firstname: "Kate", id: 318, /*...*/ }, { firstname: "Anna", id: 319, /*...*/ }, { firstname: "Cristine", id: 317, /*...*/ }, ] console.log(users.sort((a,b)=> (a.firstname>b.firstname)*2-1) );8Inspired from this answer,
users.sort((a,b) => (a.firstname - b.firstname)); 5also for both asec and desc sort, u can use this : suppose we have a variable SortType that specify ascending sort or descending sort you want:
users.sort(function(a,b){ return sortType==="asc"? a.firstName.localeCompare( b.firstName): -( a.firstName.localeCompare( b.firstName)); }) A generalized function can be written like below
function getSortedData(data, prop, isAsc) { return data.sort((a, b) => (a[prop] < b[prop] ? -1 : 1) * (isAsc ? 1 : -1)); } you can pass the below parameters
- The data which you want to sort
- The property in the data by it should be sorted
- The last parameter is of boolean type. It checks if you want to sort by ascending or by descending
in simply words you can use this method
users.sort(function(a,b){return a.firstname < b.firstname ? -1 : 1}); You can use this for objects
transform(array: any[], field: string): any[] { return array.sort((a, b) => a[field].toLowerCase() !== b[field].toLowerCase() ? a[field].toLowerCase() < b[field].toLowerCase() ? -1 : 1 : 0);} Just for the record, if you want to have a named sort-function, the syntax is as follows:
let sortFunction = (a, b) => { if(a.firstname < b.firstname) { return -1; } if(a.firstname > b.firstname) { return 1; } return 0; }) users.sort(sortFunction) Note that the following does NOT work:
users.sort(sortFunction(a,b)) Pushed the top answers into a prototype to sort by key.
Array.prototype.alphaSortByKey= function (key) { this.sort(function (a, b) { if (a[key] < b[key]) return -1; if (a[key] > b[key]) return 1; return 0; }); return this; }; You can use the in-built array method - sort. This method takes a callback method as a param
// custom sort function to be passed as param/callback to the Array's sort method function myCustomSort(a, b) { return (a.toLowerCase() > b.toLowerCase()) ? 1 : -1; } // Actual method to be called by entity that needs sorting feature function sortStrings() { var op = Array.prototype.sort.call(arguments, myCustomSort); } // Testing the implementation var sortedArray = sortStrings("Burger", "Mayo1", "Pizza", "boxes", "Apples", "Mayo"); console.log(sortedArray); //["Apples", "boxes", "Burger", "Mayo", "Mayo1", "Pizza"] Key Points to be noted for understanding this code.
- The custom method, in this case,
myCustomSort, should return +1 or -1 for each element pair(from the input array) comparison. - Use
toLowerCase()/toUpperCase()in the custom sorting callback method so that case difference does not affect the correctness of the sorting process.
I hope this is clear enough explanation. Feel free to comment if you think, more info is needed.
Cheers!
2You can use something similar, to get rid of case sensitive
users.sort(function(a, b){ //compare two values if(a.firstname.toLowerCase() < b.firstname.toLowerCase()) return -1; if(a.firstname.toLowerCase() > b.firstname.toLowerCase()) return 1; return 0; }) 1My implementation, works great in older ES versions:
sortObject = function(data) { var keys = Object.keys(data); var result = {}; keys.sort(); for(var i = 0; i < keys.length; i++) { var key = keys[i]; result[key] = data[key]; } return result; }; for a two factors sort (name and lastname):
users.sort((a, b) => a.name.toLowerCase() < b.name.toLowerCase() ? -1 : a.name.toLowerCase() > b.name.toLowerCase() ? 1 : a.lastname.toLowerCase() < b.lastname.toLowerCase() ? -1 : a.lastname.toLowerCase() > b.lastname.toLowerCase() ? 1 : 0)