JS06
JS06

Reputation: 15

JavaScript Sorting Array Based On Condition

If I have an array of below items and I want to display all the IsImportant=true items sorted first and then IsImportant=false items sorted next.

var sampleArray = [{
  "Name": "A",
  "IsImportant": true
}, {
  "Name": "B",
  "IsImportant": true
}, {
  "Name": "C",
  "IsImportant": false
}, {
  "Name": "D",
  "IsImportant": false
}, {
  "Name": "E",
  "IsImportant": false
},, {
  "Name": "F",
  "IsImportant": true
},
, {
  "Name": "G",
  "IsImportant": true
}, {
  "Name": "H",
  "IsImportant": false
}];

I was trying to write a compareFunction like below to reach the result but didn't succeed. Would there be any better alternative?

function comparator(a, b) {
  //console.log(a,b); 
  if (a.IsImportant || b.IsImportant) {
    if (a.Name > b.Name) {
      return 1;
    }
    if (a.Name < b.Name) {
      return -1;
    }
  }
  return 0;
};

Fiddle

Upvotes: 0

Views: 85

Answers (2)

kevin ternet
kevin ternet

Reputation: 4612

And why not just this :

var sampleArray = [{
  "Name": "A",
  "IsImportant": true
}, {
  "Name": "B",
  "IsImportant": true
}, {
  "Name": "C",
  "IsImportant": false
}, {
  "Name": "D",
  "IsImportant": false
}, {
  "Name": "E",
  "IsImportant": false
},, {
  "Name": "F",
  "IsImportant": true
},
, {
  "Name": "G",
  "IsImportant": true
}, {
  "Name": "H",
  "IsImportant": false
}];

var results = sampleArray.filter(x => x.IsImportant).concat(sampleArray.filter(x => !x.IsImportant));
console.log(results);

Upvotes: 0

Pointy
Pointy

Reputation: 413727

What you're trying to do is sort on 2 keys: first, the "IsImportant" key, and second, the names. The comparator should check each key in order and only move on to subsequent keys when the higher-priority keys are equal.

Thus:

function comparator(a, b) {
  //console.log(a,b); 
  if (a.IsImportant && !b.IsImportant)
    return 1;

  if (!a.IsImportant && b.IsImportant)
    return -1;

  return a.Name.localeCompare(b.Name);
};

(The .localeCompare() function is a handy way to compare strings for sorting.)

You could take advantage of the fact that JavaScript will treat the Boolean constants true and false as 1 and 0 when they're used with (some) math operators, so you could shorten that a little:

function comparator(a, b) {
  var diff = b.IsImportant - a.IsImportant;
  if (diff) return diff;
  return a.Name.localeCompare(b.Name);
}

Either way, the comparator doesn't bother to compare the names when the "IsImportant" flag is different. When both of those flags are true or false for the two items being compared, then the names are checked. That way, you'll get all the important ones first in name order, and then all the other important ones.

Upvotes: 2

Related Questions