Sort objects in an array alphabetically on one property of the array

Javascript

Javascript Problem Overview


Let's say you have a JavaScript class like this

var DepartmentFactory = function(data) {
    this.id = data.Id;
    this.name = data.DepartmentName;
    this.active = data.Active;
}

Let's say you then create a number of instances of that class and store them in an array

var objArray = [];
objArray.push(DepartmentFactory({Id: 1, DepartmentName: 'Marketing', Active: true}));
objArray.push(DepartmentFactory({Id: 2, DepartmentName: 'Sales', Active: true}));
objArray.push(DepartmentFactory({Id: 3, DepartmentName: 'Development', Active: true}));
objArray.push(DepartmentFactory({Id: 4, DepartmentName: 'Accounting', Active: true}));

So I now would have an array of objects created by DepartmentFactory. How would I go about using the array.sort() method to sort this array of objects by the DepartmentName property of each object?

The array.sort() method works just fine when sorting an array of strings

var myarray=["Bob", "Bully", "Amy"];
myarray.sort(); //Array now becomes ["Amy", "Bob", "Bully"]

But how do I make it work with a list of objects?

Javascript Solutions


Solution 1 - Javascript

you would have to do something like this:

objArray.sort(function(a, b) {
    var textA = a.DepartmentName.toUpperCase();
    var textB = b.DepartmentName.toUpperCase();
    return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
});

note: changing the case (to upper or lower) ensures a case insensitive sort.

Solution 2 - Javascript

To support unicode:

objArray.sort(function(a, b) {
   return a.DepartmentName.localeCompare(b.DepartmentName);
});

Solution 3 - Javascript

Shorter code with ES6

objArray.sort((a, b) => a.DepartmentName.toLowerCase().localeCompare(b.DepartmentName.toLowerCase()))

Solution 4 - Javascript

objArray.sort((a, b) => a.DepartmentName.localeCompare(b.DepartmentName))

Solution 5 - Javascript

var DepartmentFactory = function(data) {
    this.id = data.Id;
    this.name = data.DepartmentName;
    this.active = data.Active;
}

// use `new DepartmentFactory` as given below. `new` is imporatant

var objArray = [];
objArray.push(new DepartmentFactory({Id: 1, DepartmentName: 'Marketing', Active: true}));
objArray.push(new DepartmentFactory({Id: 2, DepartmentName: 'Sales', Active: true}));
objArray.push(new DepartmentFactory({Id: 3, DepartmentName: 'Development', Active: true}));
objArray.push(new DepartmentFactory({Id: 4, DepartmentName: 'Accounting', Active: true}));

function sortOn(property){
    return function(a, b){
        if(a[property] < b[property]){
            return -1;
        }else if(a[property] > b[property]){
            return 1;
        }else{
            return 0;   
        }
    }
}

//objArray.sort(sortOn("id")); // because `this.id = data.Id;`
objArray.sort(sortOn("name")); // because `this.name = data.DepartmentName;`
console.log(objArray);

demo: http://jsfiddle.net/diode/hdgeH/

Solution 6 - Javascript

// Sorts an array of objects "in place". (Meaning that the original array will be modified and nothing gets returned.)
function sortOn (arr, prop) {
    arr.sort (
	    function (a, b) {
		    if (a[prop] < b[prop]){
			    return -1;
		    } else if (a[prop] > b[prop]){
			    return 1;
		    } else {
			    return 0;   
		    }
	    }
    );
}

//Usage example:

var cars = [
		{make:"AMC", 		model:"Pacer", 	year:1978},
		{make:"Koenigsegg", model:"CCGT", 	year:2011},
		{make:"Pagani", 	model:"Zonda", 	year:2006},
		];

// ------- make -------
sortOn(cars, "make");
console.log(cars);

/* OUTPUT:
AMC 		: Pacer : 1978
Koenigsegg 	: CCGT 	: 2011
Pagani 		: Zonda : 2006
*/



// ------- model -------
sortOn(cars, "model");
console.log(cars);

/* OUTPUT:
Koenigsegg 	: CCGT 	: 2011
AMC 		: Pacer : 1978
Pagani 		: Zonda : 2006
*/



// ------- year -------
sortOn(cars, "year");
console.log(cars);

/* OUTPUT:
AMC 		: Pacer : 1978
Pagani 		: Zonda : 2006
Koenigsegg 	: CCGT 	: 2011
*/

Solution 7 - Javascript

objArray.sort( (a, b) => a.id.localeCompare(b.id, 'en', {'sensitivity': 'base'}));

This sorts them alphabetically AND is case insensitive. It's also super clean and easy to read :D

Solution 8 - Javascript

http://jsfiddle.net/RcbeN/">DEMO</a></h1>

var DepartmentFactory = function(data) {
    this.id = data.Id;
    this.name = data.DepartmentName;
    this.active = data.Active;
}

var objArray = [];
objArray.push(new DepartmentFactory({Id: 1, DepartmentName: 'Marketing', Active: true}));
objArray.push(new DepartmentFactory({Id: 2, DepartmentName: 'Sales', Active: true}));
objArray.push(new DepartmentFactory({Id: 3, DepartmentName: 'Development', Active: true}));
objArray.push(new DepartmentFactory({Id: 4, DepartmentName: 'Accounting', Active: true}));

console.log(objArray.sort(function(a, b) { return a.name > b.name}));

Solution 9 - Javascript

do it like this

objArrayy.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)
});
console.log(objArray)

Solution 10 - Javascript

Because all of the solutions here were presented without null/undefined safe operations, I handle that this way (you can handle nulls as you see fit):

ES5

objArray.sort(
  function(a, b) {
    var departmentNameA = a.DepartmentName ? a.DepartmentName : '';
    var departmentNameB = b.DepartmentName ? b.DepartmentName : '';

    departmentNameA.localeCompare(departmentNameB);
  }
);

ES6+

objArray.sort(
 (a: DepartmentFactory, b: DepartmentFactory): number => {
   const departmentNameA = a.DepartmentName ? a.DepartmentName : '';
   const departmentNameB = b.DepartmentName ? b.DepartmentName : '';

   departmentNameA.localeCompare(departmentNameB);
 }
);

I have also removed the toLowerCase that others used since localeCompare is case insensitive. Also I prefer to be a bit more explicit on parameters when using Typescript or ES6+ to make it more explicit for future developers.

Solution 11 - Javascript

Here is a simple function you can use to sort array of objects through their properties; it doesn't matter if the property is a type of string or integer, it will work.

    var cars = [
        {make:"AMC",        model:"Pacer",  year:1978},
        {make:"Koenigsegg", model:"CCGT",   year:2011},
        {make:"Pagani",     model:"Zonda",  year:2006},
    ];

    function sortObjectsByProp(objectsArr, prop, ascending = true) {
        let objectsHaveProp = objectsArr.every(object => object.hasOwnProperty(prop));
        if(objectsHaveProp)    {
            let newObjectsArr = objectsArr.slice();
            newObjectsArr.sort((a, b) => {
                if(isNaN(Number(a[prop])))  {
                    let textA = a[prop].toUpperCase(),
                        textB = b[prop].toUpperCase();
                    if(ascending)   {
                        return textA < textB ? -1 : textA > textB ? 1 : 0;
                    } else {
                        return textB < textA ? -1 : textB > textA ? 1 : 0;
                    }
                } else {
                    return ascending ? a[prop] - b[prop] : b[prop] - a[prop];
                }
            });
            return newObjectsArr;
        }
        return objectsArr;
    }

    let sortedByMake = sortObjectsByProp(cars, "make"); // returns ascending order by its make;
    let sortedByYear = sortObjectsByProp(cars, "year", false); // returns descending order by its year,since we put false as a third argument;
    console.log(sortedByMake);
    console.log(sortedByYear);

Solution 12 - Javascript

You have to pass a function that accepts two parameters, compares them, and returns a number, so assuming you wanted to sort them by ID you would write...

objArray.sort(function(a,b) {
    return a.id-b.id;
});
// objArray is now sorted by Id

Solution 13 - Javascript

After try a little bit on this, and trying to make less loops as possible, I ended up with this solution:

Demo on codepen

const items = [
      {
        name: 'One'
      },
      {
        name: 'Maria is here'
      },
      {
        name: 'Another'
      },
      {
        name: 'Z with a z'
      },
      {
        name: '1 number'
      },
      {
        name: 'Two not a number'
      },
      {
        name: 'Third'
      },
      {
        name: 'Giant'
      }
    ];
    
    const sorted = items.sort((a, b) => {
      return a[name] > b[name];
    });
    
    let sortedAlphabetically = {};
    
    for(var item in sorted) {
      const firstLetter = sorted[item].name[0];
      if(sortedAlphabetically[firstLetter]) {
        sortedAlphabetically[firstLetter].push(sorted[item]);
      } else {
        sortedAlphabetically[firstLetter] = [sorted[item]]; 
      }
    }
    
    console.log('sorted', sortedAlphabetically);

Solution 14 - Javascript

A simple answer:

objArray.sort(function(obj1, obj2) {
   return obj1.DepartmentName > obj2.DepartmentName;
});

ES6 way:

objArray.sort((obj1, obj2) => {return obj1.DepartmentName > obj2.DepartmentName};

If you need to make it lowercase/uppercase etc, just do that and store that result in a variable than compare that variable. Example:

objArray.sort((obj1, obj2) => {
   var firstObj = obj1.toLowerCase();
   var secondObj = obj2.toLowerCase();
   return firstObj.DepartmentName > secondObj.DepartmentName;
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjdavisView Question on Stackoverflow
Solution 1 - JavascriptOmer BokhariView Answer on Stackoverflow
Solution 2 - Javascriptron tornambeView Answer on Stackoverflow
Solution 3 - JavascriptLudovicView Answer on Stackoverflow
Solution 4 - JavascriptNeilView Answer on Stackoverflow
Solution 5 - JavascriptDiodeView Answer on Stackoverflow
Solution 6 - JavascriptbobView Answer on Stackoverflow
Solution 7 - JavascriptAlissaView Answer on Stackoverflow
Solution 8 - JavascriptqwertymkView Answer on Stackoverflow
Solution 9 - JavascriptnickleeflyView Answer on Stackoverflow
Solution 10 - JavascriptKris BoydView Answer on Stackoverflow
Solution 11 - JavascriptMichael NorwardView Answer on Stackoverflow
Solution 12 - Javascriptzconnelly13View Answer on Stackoverflow
Solution 13 - JavascriptAlexandre Magno Teles ZimererView Answer on Stackoverflow
Solution 14 - JavascriptMarView Answer on Stackoverflow