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: "[email protected]",
firstname: "Anna",
id: 318,
lastAvatar: null,
lastMessage: null,
lastname: "Nickson",
nickname: "anny"
};
This question is related to
javascript
Basically 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: "[email protected]",
firstname: 'Anna',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
},
{
bio: "<null>",
email: "[email protected]",
firstname: 'Senad',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
},
{
bio: "<null>",
email: "[email protected]",
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;
});
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)
_x000D_
If 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);
})
in simply words you can use this method
users.sort(function(a,b){return a.firstname < b.firstname ? -1 : 1});
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.
myCustomSort
, should return +1 or -1 for each element pair(from the input array) comparison.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!
Nice little ES6 one liner:
users.sort((a, b) => a.firstname !== b.firstname ? a.firstname < b.firstname ? -1 : 1 : 0);
also 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));
})
try
users.sort((a,b)=> (a.firstname>b.firstname)*2-1)
var users = [_x000D_
{ firstname: "Kate", id: 318, /*...*/ },_x000D_
{ firstname: "Anna", id: 319, /*...*/ },_x000D_
{ firstname: "Cristine", id: 317, /*...*/ },_x000D_
]_x000D_
_x000D_
console.log(users.sort((a,b)=> (a.firstname>b.firstname)*2-1) );
_x000D_
underscorejs 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()})
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);}
You 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;
})
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))
My 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;
};
Shortest possible code with ES6!
users.sort((a, b) => a.firstname.localeCompare(b.firstname))
String.prototype.localeCompare() basic support is universal!
Inspired from this answer,
users.sort((a,b) => (a.firstname - b.firstname));
We 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=[_x000D_
{name:'john',lname:'doe',address:'Alaska'},_x000D_
{name:'tom',lname:'hopes',address:'California'},_x000D_
{name:'harry',address:'Texas'}_x000D_
]_x000D_
let field='lname';_x000D_
console.log(obj.sort((a, b) => (a[field] || "").toString().localeCompare((b[field] || "").toString())));
_x000D_
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')
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
I'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
numeric: true,
sensitivity: 'base',
});
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;
}
A more compact notation:
user.sort(function(a, b){
return a.firstname === b.firstname ? 0 : a.firstname < b.firstname ? -1 : 1;
})
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;
};
In 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'}];_x000D_
_x000D_
_x000D_
user.sort((a, b) => a.firstname.localeCompare(b.firstname, 'es', {sensitivity: 'base'}))_x000D_
_x000D_
_x000D_
console.log(user)
_x000D_
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.
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)
});
Source: Stackoverflow.com