27

Using JavaScript, I would like to know how to sort lexicographically an array of objects based on a string value in each object.

Consider:

[
 {
    "name" : "bob",
    "count" : true
    "birthday" : 1972
 },
      {
    "name" : "jill",
    "count" : false
    "birthday" : 1922
 },
      {
    "name" : "Gerald",
    "count" : true
    "birthday" : 1920
 }
 ]

How can I sort the array alphabetically by name?

The name values are usernames, so I would like to maintain the letter casing.

2

4 Answers 4

48
var obj = [...];

obj.sort(function(a,b){return a.name.localeCompare(b.name); });

Be aware that this will not take capitalisation into account (so it will order all names beginning with capitals before all those beginning with smalls, i.e. "Z" < "a"), so you might find it relevant to add a toUpperCase() in there.

You can make it more generic as well:

function sortFactory(prop) {
   return function(a,b){ return a[prop].localeCompare(b[prop]); };
}

obj.sort(sortFactory('name')); // sort by name property
obj.sort(sortFactory('surname')); // sort by surname property

And even more generic if you pass the comparator to the factory...

Sign up to request clarification or add additional context in comments.

3 Comments

Use toLocaleUpperCase/toLocaleLowerCase instead of toUpperCase/toLowerCase.
This answer no longer holds true (at least on current chrome dev console). ["a", "A", "b", "B"].sort((a,b)=>{return a.localeCompare(b)}) expected to be ["A", "B", "a", "b"] but returns ["a", "A", "b", "B"]
what @user3240644 said. 'aaA'.localeCompare('aAA') returns -1 which sorts aaA before aAA which is incorrect in the case of lexicographic order
3

This will do it:

arr.sort(function(a, b) {
    return a.name.localeCompare(b.name);
});

2 Comments

thanks for the response, however I forgot to specify that name is actually a username in my data's case, so I want to maintain the casing that is supplied
No problem; I've updated my code. Glad it's sorted via @davin's answer.
1

Using comparison

arr.sort(function (a, b) {return a.name.toLowerCase() > b.name.toLowerCase()})

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String#Comparing_strings

Comments

0

I read in this post sort array lexicographically in javascript to just use sort directly and not localeCompare and this seems to do the trick.

localeCompare does not sort lexicographically.

'aaA'.localeCompare('aAA') returns -1 which sorts aaA before aAA. In lex, capitals come first, so it should be ['aAA', 'aaA']

You can do something like this to handle a few cases.

export default function sortLex ({ arr, prop, reverse }) {
  let sorted
  if (prop) {
    sorted = arr.sort(sortFactory(prop))
  } else sorted = arr.sort(sort)

  return reverse ? sorted.reverse() : sorted
}

function sort (a, b) {
  if (a < b) {
    return -1
  }
  if (a === b) {
    return 0
  }
  if (a > b) {
    return 1
  }
}

function sortFactory (prop) {
  return (a, b) => {
    return sort(a[prop], b[prop])
  }
}

1 Comment

In your sort() function, what happens if a and b are not ordered?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.