简体   繁体   中英

how to sort array of objects by condition javascript

I have array of objects with properties.

I would like to sort by status, that is 15, 17 then 16 at last in javascript

For a array of objects, status having value 16

should be placed at last and rest should sort by ascending as the expected output.

How to do in javascript

var result = arrobj.filter(e=>e.details.status !== 16).sort(a, b) => a.status - b.status;

var arrobj = [
  {
    "id":1,
    "name": 'xyz',
    "details": {
    "job": 'fulltime',
    "status": 15
    }
  },
  { 
    "id":2,
    "name": 'abc',
    "details": {
    "job": 'partime',
    "status": 16
    }
  },
  { 
    "id":3,
    "name": 'zen',
    "details": {
    "job": 'fulltime',
    "status": 17
    }
  },
  { 
   "id":5,
    "name": 'abu',
    "details": {
    "job": 'fulltime',
    "status": 16
    }
  },
{ 
   "id":7,
    "name": 'john',
    "details": {
    "job": 'parttime',
    "status": 15
    }
  },
 { 
   "id":10,
    "name": 'jocob',
    "details": {
    "job": 'fulltime',
    "status": 17
    }
  }
]

Expected Output

[
  {
    "id":1,
    "name": 'xyz',
    "details": {
    "job": 'fulltime',
    "status": 15
    }
  },
 { 
   "id":7,
    "name": 'john',
    "details": {
    "job": 'parttime',
    "status": 15
    }
  },
  { 
    "id":3,
    "name": 'zen',
    "details": {
    "job": 'fulltime',
    "status": 17
    }
  },
 { 
   "id":10,
    "name": 'jocob',
    "details": {
    "job": 'fulltime',
    "status": 17
    }
  },
  { 
    "id":2,
    "name": 'abc',
    "details": {
    "job": 'partime',
    "status": 16
    }
  },
  { 
   "id":5,
    "name": 'abu',
    "details": {
    "job": 'fulltime',
    "status": 16
    }
  }
]


const results = [...arrobj.filter(ob => ob.details.status !== 16).sort((a,b) => a.details.status - b.details.status), ...arrobj.filter(ob => ob.details.status === 16)]

You mean this?

You had to add .status in the sort function sort() To place the object with status 16 at the end, I made an seperate array with status 16 and added on the end of the array with everything else.

var result = arrobj.filter(e=>e.details.status !== 16).sort( (a, b) => a.details.status - b.details.status);
result = result.concat(arrobj.filter(e=>e.details.status == 16));


console.log(result)

From EcmaScript 2019 Array.sort is stable. This mean that you can split that complex sorting into 2 - first by status, then placing all items with status 16 in the back. Not efficient solution

arrobj.sort((first,second) => first.details.status - second.details.status)
      .sort((first, second) => (first.details.status === 16) - (second.details.status === 16));

The below will also work for your use case. You were really close though

arrobj.filter(e=>e.details.status !== 16).sort((a, b) => {return a.details.status - b.details.status}).concat(arrobj.filter(e=>e.details.status == 16));

Your sort function is not correct. Try this one. I also add the ability to change the sort order.

// Sort by status
function sortByStatus(array, asc = true) {
  let newArray = [...array];

  // filter and sort
  if (asc) {
    newArray = newArray.filter(e => e.details.status !== 16).sort((a, b) => a.details.status > b.details.status && 1 || -1);
  } else {
    newArray = newArray.filter(e => e.details.status !== 16).sort((a, b) => a.details.status < b.details.status && 1 || -1);
  }

  return newArray;
}

// merge result
const result = [...sortByStatus(arrobj), arrobj.filter(e => e.details.status === 16)];

 var arrobj = [{ "id": 1, "name": 'xyz', "details": { "job": 'fulltime', "status": 15 } }, { "id": 2, "name": 'abc', "details": { "job": 'partime', "status": 16 } }, { "id": 3, "name": 'zen', "details": { "job": 'fulltime', "status": 17 } }, { "id": 5, "name": 'abu', "details": { "job": 'fulltime', "status": 16 } }, { "id": 7, "name": 'john', "details": { "job": 'parttime', "status": 15 } }, { "id": 10, "name": 'jocob', "details": { "job": 'fulltime', "status": 17 } } ]; // Sort by status function sortByStatus(array, asc = true) { let newArray = [...array]; // filter and sort if (asc) { newArray = newArray.filter(e => e.details.status.== 16),sort((a. b) => a.details.status > b.details;status && 1 || -1). } else { newArray = newArray.filter(e => e.details.status,== 16).sort((a. b) => a.details.status < b;details;status && 1 || -1). } return newArray. } // merge result const result = [.,.sortByStatus(arrobj). arrobj.filter(e => e;details.status === 16)]; console.log(result);

We can customize sort rules using the compareFn in Array.prototype.sort(compareFn) .

Example:

var result = arrobj
    .sort((obja, objb) => {
        let a = obja.details.status
        let b = objb.details.status
        if (a == 16) a = Number.MAX_SAFE_INTEGER
        if (b == 16) b = Number.MAX_SAFE_INTEGER
        return a - b
    })

for es5

 arrobj.sort((a, b) => {
     if (a.details.status === 16) {
         return 1;
     } else if (b.details.status === 16) {
         return -1
     } else {
         return a.details.status - b.details.status
     }
  })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM