根据带有空值的多个条件对对象数组排序

Sorting an array of objects by multiple criteria with null values

本文关键字:条件 对象 数组排序 空值      更新时间:2023-09-26

好了,我有一个对象数组,其中包含某个属性的空值

对象看起来大致像这样的排序目的…(40个元素,但这就足够了…)。

需要按照roulette降序排序(roulette有时为空),然后是novelty,然后是popularity

我的头有点碎了。

这可以按降序对roulette进行排序,但是我需要如何扩展它以包括其他两个标准?

对象:

[
 {
  title: 'one',
  popularity: 4,
  novelty: 3
 },
 {
  title: 'two',
  popularity: 1
  novelty: 4
 },
 {
  title: 'three',
  popularity: 5,
  novelty: 3,
  roulette: 0
 },
 {
  title: 'four',
  popularity: 5,
  novelty: 3,
  roulette: 1
 }
]

部分工作功能:

  object.sort(function(a, b) {
    if (a['roulette'] == null) return 1
    if (b['roulette'] == null) return -1
    if (a['roulette'] === b['roulette']) return 0
    return b.roulette > a.roulette ? 1 : -1
  });

尝试使用优先级和组进行排序。

var data = [{ title: 'one', popularity: 4, novelty: 3 }, { title: 'two', popularity: 1, novelty: 4 }, { title: 'three', popularity: 5, novelty: 3, roulette: 0 }, { title: 'four', popularity: 5, novelty: 3, roulette: 1 }, { title: 'five', popularity: 5, novelty: 4, roulette: null }, { title: 'six', popularity: 5, novelty: 5, roulette: undefined }];
data.sort(function (a, b) {
    return (
        (a.roulette === undefined || a.roulette === null) - (b.roulette === undefined || b.roulette === null) ||
        a.roulette - b.roulette ||
        a.novelty - b.novelty ||
        a.popularity - b.popularity
    );       
});
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

您可以尝试基于加权排名的排序:

var data=[{title:"one",popularity:4,novelty:3},{title:"two",popularity:1,novelty:4},{title:"three",popularity:5,novelty:3,roulette:0},{title:"four",popularity:5,novelty:3,roulette:1}];
data.sort(function(a, b) {
  var r1 = a.roulette === undefined ? -1 : a.roulette;
  var r2 = b.roulette === undefined ? -1 : b.roulette;
  var n1 = a.novelty === undefined ? -1 : a.novelty;
  var n2 = b.novelty === undefined ? -1 : b.novelty;
  var p1 = a.popularity === undefined ? -1 : a.popularity;
  var p2 = b.popularity === undefined ? -1 : b.popularity;
  var r_rank = r1 > r2 ? -100 : r1 < r2 ? 100 : 0;
  var n_rank = n1 > n2 ? -10 : n1 < n2 ? 10 : 0;
  var p_rank = p1 > p2 ? -1 : p1 < p2 ? 1 : 0;
  return r_rank + n_rank + p_rank;
})
var r_rank = r1 > r2 ? -100 : r1 < r2 ? 100 : 0;
var n_rank = n1 > n2 ? -10 : n1 < n2 ? 10 : 0;
var p_rank = p1 > p2 ? -1 : p1 < p2 ? 1 : 0;
return r_rank + n_rank + p_rank;
})
console.log(data)

只需包含更多条件:

var data = [{"title":"one","popularity":4,"novelty":3},{"title":"two","popularity":1,"novelty":4},{"title":"three","popularity":5,"novelty":3,"roulette":0},{"title":"four","popularity":5,"novelty":3,"roulette":1}];
data.sort(function(a,b) {
  if (a.roulette < b.roulette || a.roulette == null) return +1;
  if (a.roulette > b.roulette || b.roulette == null) return -1;
  if (a.novelty < b.novelty || a.novelty == null) return +1;
  if (a.novelty > b.novelty || b.novelty == null) return -1;
  if (a.popularity < b.popularity || a.popularity == null) return +1;
  if (a.popularity > b.popularity || b.popularity == null) return -1;
  return 0;
})
console.log(data);

如果一个参数相同,你只需要继续打破联系。

 obj.sort(function(a, b) {
    var rouletteDiff = compare(a.roulette, b.roulette);
    if(rouletteDiff != 0) return rouletteDiff;
    var noveltyDiff = compare(a.novelty, b.novelty);
    if(noveltyDiff != 0) return noveltyDiff;
    return compare(a.popularity, b.popularity);
  });
  function compare(x,y){
    if(x == undefined) return 1;
    if(y == undefined) return -1;
    if(x === y){
        return 0;
    }else{
        return x > y ? -1 : 1
    }
  }

这是roulette, noveltypopularity(按顺序)的优先排序(降序)

这处理 nullundefined -查看下面的演示:

var object=[{title:"one",popularity:4,novelty:3},{title:"two",popularity:1,novelty:4},{title:"three",popularity:5,novelty:3,roulette:0},{title:"four",popularity:5,novelty:3,roulette:1},{title:"five",roulette:4,novelty:null},{title:"six",popuplarity:7},{title:"seven",novelty:8,roulette:null},{title:"eight",novelty:0},{title:"nine",popularity:10}];
function ifNumber(num) {
  if(num == undefined || num == null)
    return -Infinity;
  else
    return num;
}
var result = object.sort(function(a, b) {
  return (ifNumber(b.roulette) - ifNumber(a.roulette)) 
      || (ifNumber(b.novelty) - ifNumber(a.novelty))
      || (ifNumber(b.popuplarity) - ifNumber(a.popuplarity));
});
console.log(result);
.as-console-wrapper{top:0;max-height:100%!important;}