2

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
    }
  }
]


2
  • Why are you filter object with status 16 if you need it ? Commented Feb 4, 2022 at 7:14
  • @SimoneRossaini thanks for reply, I need to get array of objects with status 15,17,16 so I thought filter not equal to 16 first, then sort rest ascending and add the object with status 16 at last, but i got stuck to do Commented Feb 4, 2022 at 7:17

7 Answers 7

2

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
    })
Sign up to request clarification or add additional context in comments.

Comments

1
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?

Comments

1

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
     }
  })

Comments

0

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));

Comments

0

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));

Comments

0

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);

Comments

0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.