Search code examples
javascripttypescriptecmascript-6ecmascript-5

Sort an array of objects according to two properties values


I have an array of objects:

let items = [
  { name: 'eric', type: 'comparable',  value: 1 },
  { name: 'bob', type: 'comparable', value: 4 },
  { name: 'michael', type: 'comparable', value: 0 },
  { name: 'john', type: 'comparable', value: 3 },
  { name: 'brad', type: 'incomparable', value: null },
  { name: 'james', type: 'incomparable', value: 5},
  { name: 'martin', type: 'comparable', value: 2 },
  { name: 'chris', type: 'comparable', value: null }
];

I want to sort my array so that the objects can be sorted by:

  • First, according to "type" property -> if it's = "Comparable" -> sort it according to the "value" property

  • Second, according to the "value" property -> if it's null make it in the bottom of the array

by the "value" attribute, and if it's null, make the object in the bottom of the array, to be like this:

  { name: 'michael', type: 'comparable', value: 0 },
  { name: 'eric', type: 'comparable',  value: 1 },
  { name: 'martin', type: 'comparable', value: 2 },
  { name: 'john', type: 'comparable', value: 3 },
  { name: 'bob', type: 'comparable', value: 4 },
  { name: 'chris', type: 'comparable', value: null },
  { name: 'brad', type: 'incomparable', value: null },
  { name: 'james', type: 'incomparable', value: 5}

I've done this:

items.sort((a, b) => {
    return (a.value===null)-(b.value===null) || +(a.value>b.value)||-(a.ordre<b);
});

But like that I'm sorting always according to the "value" property, I want that it looks first for the property

(I won't use loadash)

Suggestions ?


Solution

  • I personally find it easier to read if the logic reads similar to the way you describe it. In this example I've tried to take the requirements as you've described it into a series of if statements instead of a single logical expression:

    let items = [
      { name: 'eric', type: 'comparable',  value: 1 },
      { name: 'bob', type: 'comparable', value: 4 },
      { name: 'michael', type: 'comparable', value: 0 },
      { name: 'john', type: 'comparable', value: 3 },
      { name: 'brad', type: 'incomparable', value: null },
      { name: 'james', type: 'incomparable', value: 5},
      { name: 'martin', type: 'comparable', value: 2 },
      { name: 'chris', type: 'comparable', value: null }
    ];
    
    console.log(items.sort((a, b) => {
      if (a.type === 'comparable' && b.type === 'comparable') {
        if (a.value == null) return 1;
        return a.value - b.value;
      }
      if (a.type === 'comparable') return -1;
      return 1;
    }));