totalnoob
totalnoob

Reputation: 2741

find different matches and resort array in javascript

I'm wondering how one would resort an array based on whether or not a property exists within each object. this is what would come back from the backend, only one has the something field, and only one has a false value for its isActive property.

I'd need the one or ones that has a something property sorted to the top of the array and secondly all the ones with a true value for its isActive property comes before the ones with false.

so this

    var obj = [
      {
        "_id": "58f8ffe7ce2bbf01c6164802",
        "isActive": false
      },
	  {
        "_id": "58f8ffe7ce2bbf01c6164803",
        "isActive": true
      },
      {
        "_id": "58f8ffe7ce2bbf01c6164804",
        "isActive": true
      },       
      { 
       "_id": "58f8ffe7ce2bbf01c6164801",
        "isActive": true,
        { "something": "xyz" }
      },
 	  {
        "_id": "58f8ffe7ce2bbf01c6164806",
        "isActive": true
      },
        {
        "_id": "58f8ffe7ce2bbf01c6164807",
        "isActive": true
      },
        {
        "_id": "58f8ffe7ce2bbf01c6164808",
        "isActive": true
      },
        {
        "_id": "58f8ffe7ce2bbf01c6164809",
        "isActive": true
      },
        {
        "_id": "58f8ffe7ce2bbf01c6164810",
        "isActive": true
      }
    ]

would become

        var obj = [
          { 
           "_id": "58f8ffe7ce2bbf01c6164801",
            "isActive": true,
            { "something": "xyz" }
          },
    	  {
            "_id": "58f8ffe7ce2bbf01c6164803",
            "isActive": true
          },
          {
            "_id": "58f8ffe7ce2bbf01c6164804",
            "isActive": true
          },       
 
     	  {
            "_id": "58f8ffe7ce2bbf01c6164806",
            "isActive": true
          },
            {
            "_id": "58f8ffe7ce2bbf01c6164807",
            "isActive": true
          },
            {
            "_id": "58f8ffe7ce2bbf01c6164808",
            "isActive": true
          },
            {
            "_id": "58f8ffe7ce2bbf01c6164809",
            "isActive": true
          },
            {
            "_id": "58f8ffe7ce2bbf01c6164810",
            "isActive": true
          },
          
          {
            "_id": "58f8ffe7ce2bbf01c6164802",
            "isActive": false
          },
        ]

two different types of searching and matching and then an array.push? would helpers like lodash be practical, would it be easier with jQuery or can it simply be done with vanilla js?

Upvotes: 1

Views: 113

Answers (2)

mmohammad
mmohammad

Reputation: 2802

Here is how I would do it in ES6.

The sort logic below simply tests the existence of the property something, if it doesn't, then checks the property isActive

let obj = [
  {
    "_id": "58f8ffe7ce2bbf01c6164803",
    "isActive": false
  },
  {
    "_id": "58f8ffe7ce2bbf01c6164804",
    "isActive": true
  },
  {
    "_id": "58f8ffe7ce2bbf01c6164803",
    "isActive": false
  },
  {
    "_id": "58f8ffe7ce2bbf01c6164804",
    "isActive": true
  },
  {
   "_id": "58f8ffe7ce2bbf01c6164801",
    "isActive": true,
    "something": "xyz"
  }
  ];

obj.sort((a, b) => (
  (a.hasOwnProperty('something') || b.hasOwnProperty('something'))
    ? 1                     // if the above line evaluates to  true, return one
    : (a.isActive ? -1 : 1) // else evaluate this 
));
console.log(obj);

// [ { _id: '58f8ffe7ce2bbf01c6164801',
//     isActive: true,
//     something: 'xyz' },
//   { _id: '58f8ffe7ce2bbf01c6164804', isActive: true },
//   { _id: '58f8ffe7ce2bbf01c6164804', isActive: true },
//   { _id: '58f8ffe7ce2bbf01c6164803', isActive: false },
//   { _id: '58f8ffe7ce2bbf01c6164803', isActive: false } ]

Upvotes: 1

ibrahim mahrir
ibrahim mahrir

Reputation: 31692

var arr = [{"_id":"58f8ffe7ce2bbf01c6164802","isActive":false,"something":"xyz"},{"_id":"58f8ffe7ce2bbf01c6164803","isActive":false},{"_id":"58f8ffe7ce2bbf01c6164804","isActive":true},{"_id":"58f8ffe7ce2bbf01c6164801","isActive":true,"something":"xyz"},{"_id":"58f8ffe7ce2bbf01c6164806","isActive":true},{"_id":"58f8ffe7ce2bbf01c6164807","isActive":true},{"_id":"58f8ffe7ce2bbf01c6164808","isActive":true},{"_id":"58f8ffe7ce2bbf01c6164809","isActive":true},{"_id":"58f8ffe7ce2bbf01c6164810","isActive":true}];


arr.sort(function(a, b) {
  if(a.hasOwnProperty("something") && !b.hasOwnProperty("something"))       // if a has the property "something" and b doesn't
    return -1;                                                              // then put a above b
  else if(!a.hasOwnProperty("something") && b.hasOwnProperty("something"))  // otherwise if b has the property and a doesn't
    return 1;                                                               // then put b above a

    // otherwise, either both or none of them have it (then sort using the property "isActive")
    return a.isActive? -1: 1;   // if a has "isActive" set to true put it on top of b without checking for b's "isActive", otherwise, put it below
});

console.log(arr);

Edit:

var arr = [{"_id":"58f8ffe7ce2bbf01c6164802","isActive":false,"something":"xyz"},{"_id":"58f8ffe7ce2bbf01c6164803","isActive":false},{"_id":"58f8ffe7ce2bbf01c6164804","isActive":true},{"_id":"58f8ffe7ce2bbf01c6164801","isActive":true,"something":"xyz"},{"_id":"58f8ffe7ce2bbf01c6164806","isActive":true},{"_id":"58f8ffe7ce2bbf01c6164807","isActive":true},{"_id":"58f8ffe7ce2bbf01c6164808","isActive":true},{"_id":"58f8ffe7ce2bbf01c6164809","isActive":true},{"_id":"58f8ffe7ce2bbf01c6164810","isActive":true}];


arr.sort(function(a, b) {
  var aHasIt = a.something && a.something.length > 0,
      bHasIt = b.something && b.something.length > 0;
  if(aHasIt && !bHasIt)
    return -1; 
  else if(!aHasIt && bHasIt)
    return 1;

    return a.isActive? -1: 1;
});

console.log(arr);

Upvotes: 3

Related Questions