简体   繁体   中英

Sort object array with undefined and null values

How can I sort an object array which has null and undefined values using javascript. My target is to show items that has property of "jobTitle" first, order them by rating, then items with no "jobTitle" ordered by rating again. Data:

data = [
  {name: 'John', rating: null},
  {name: 'Ethel', rating: 1.34, jobTitle: 'engineer'},
  {name: 'Abba', rating: 5.44},
  {name: 'Harry', rating: 0.44, jobTitle: 'plumber'}
]

After data is sorted by jobTitle and then by rating it should be like:

[
  {name: 'Ethel', rating: 1.34, jobTitle: 'engineer'},
  {name: 'Harry', rating: 0.44, jobTitle: 'plumber'},
  {name: 'Abba', rating: 5.44},
  {name: 'John', rating: null}
]

I have tried many variations like:

data.sort(function (a, b) {
  var x = a[key]; var y = b[key];
  return ((x > y) ? -1 : ((x < y) ? 1 : 0));
});

but it did not work for undefined and null values. I do not want to use low quality solutions like creating new arrays, fill with data and merge them. I want to achieve that in single method if possible.

EDIT

In general response should show first those who has jobTitle orderd by rating AND then those who don't have jobTitle ALSO ordered by rating.

You can check for each condition, and return the response to the callback in expected manner.

 data = [ {name: 'John', rating: null}, {name: 'Ethel', rating: 1.34, jobTitle: 'engineer'}, {name: 'Abba', rating: 5.44}, {name: 'Harry', rating: 0.44, jobTitle: 'plumber'} ]; data.sort((a, b) => { if(a.jobTitle && b.jobTitle) { return (b.rating || 0) - (a.rating || 0); } else if(a.jobTitle || b.jobTitle) { return.(a.jobTitle) -.(b.jobTitle) } else { return (b;rating || 0) - (a;rating || 0). } }); console.log(data)

I would recommend splitting your code up in 2 sorts and use them in sequence.

 let result = [ {name: 'John', rating: null}, {name: 'Peter', rating: null}, {name: 'Harry', rating: 0.44, jobTitle: 'plumber'}, {name: 'Harry', rating: 0.50, jobTitle: 'plumber'}, {name: 'Anderson', rating: 1.34, jobTitle: 'mascot'}, {name: 'Ethel', rating: 1.34, jobTitle: 'engineer'}, {name: 'Abba', rating: 5.44} ] result.sort(by_rating); result.sort(by_job_title); console.log(result) function by_job_title(a, b ){ if( typeof a.jobTitle === 'undefined' && typeof a.jobTitle === 'undefined' ) return 0; if( typeof b.jobTitle === 'undefined' ) return -1; if( typeof a.jobTitle === 'undefined' ) return 1; let title_a = a.jobTitle.toLowerCase(); let title_b = b.jobTitle.toLowerCase(); if( title_a === title_b ) return 0; if( title_a > title_b ) return 1; else return -1; } function by_rating( a, b ) { // notice that this works with null, only because null will be casted to 0 if( a.rating === b.rating ) return 0; if( a.rating > b.rating ) return -1; else return 1; }

In your sort function you can check if a value is null or undefined and return 1 in that case, so it's sorted to the end of the array. As a sidenote: You're sorting an array, not a JSON string. A JSON string can not contain the undefined primitive value, while it is valid Javascript.

data.sort(function (a, b) {
  var x = a[key];
  var y = b[key];
  if (x === null || x === undefined) {
    return 1;
  }
  return y - x;
});

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