根据主对象中另一个对象列表的 属性 值对复杂 javascript 对象进行排序

Sort complex javascript objects based on property value of another list of objects inside main object

我有以下结构中的对象列表,这些对象已在顶层按名称 属性 排序。

 [{
     name: 'name1'
     team: 'team1'
     statuses: [{ time: 'day1', color: 'green', message: 'looks good'}, { time: 'day2', color: 'green', message: 'looks good'}]
    },
    {
     name: 'name2'
     team: 'team2'
     statuses: [{ time: 'day1', color: 'yellow', message: 'mild concern'}, { time: 'day2', color: 'red', message: 'critical issue'}]
    },
    {
     name: 'name3'
     team: 'team3'
     statuses: [{ time: 'day1', color: 'orange', message: 'mild concern'}, { time: 'day2', color: 'orange', message: 'potential issue'}]
    }]

以上列表应根据状态列表中最后一个对象的颜色 属性 使用自定义排序顺序(红色、橙色、绿色)进行排序。预期列表包含此顺序的对象 team2、team3、team1,如果有多个相同颜色,则它应该在顶层保留名称 属性 的排序。

我尝试按以下方式使用 reduce 函数并将它们组合在一起,但没有得到预期的输出。

 teams.reduce((r, t) => {
     if(t.statuses[1].color === 'red');
       r.push(t)
    return r;
   }, { [] })
  
   teams.reduce((r, t) => {
     if(t.statuses[1].color === 'orange');
       r.push(t)
    return r;
   }, { [] })

   teams.reduce((r, t) => {
     if(t.statuses[1].color === 'green');
       r.push(t)
    return r;
   }, { [] })

您可以创建一个定义颜色顺序的对象,然后使用 sort 方法,首先按颜色排序,如果颜色相同,则按名称排序

const data = [{"name":"name1","team":"team1","statuses":[{"time":"day1","color":"green","message":"looks good"},{"time":"day2","color":"green","message":"looks good"}]},{"name":"name2","team":"team2","statuses":[{"time":"day1","color":"yellow","message":"mild concern"},{"time":"day2","color":"red","message":"critical issue"}]},{"name":"name3","team":"team3","statuses":[{"time":"day1","color":"orange","message":"mild concern"},{"time":"day2","color":"orange","message":"potential issue"}]}]

const order = {
  red: 1,
  orange: 2,
  green: 3
}

data.sort((a, b) => {
  const aColor = a.statuses.slice(-1)[0].color;
  const bColor = b.statuses.slice(-1)[0].color;
  return order[aColor] - order[bColor] || a.name.localeCompare(b.name)
})

console.log(data)

在 original-array 上使用过滤器,我使用 COLORS-array 进行排序。因为sort-criterium中没有提到,所以我在最后添加了“黄色”颜色,你可以自己选择。

扩展:

  • 如愿,黄色现在在橙色和黄色之间分类。
  • 如果它是绿色的并且评论不是“看起来不错”那么它应该出现在开头。

let list = [{
     name: 'name1',
     team: 'team1',
     statuses: [{ time: 'day1', color: 'green', message: 'looks good'}, { time: 'day2', color: 'green', message: 'looks good'}]
    },
    {
     name: 'name2',
     team: 'team2',
     statuses: [{ time: 'day1', color: 'yellow', message: 'mild concern'}, { time: 'day2', color: 'red', message: 'critical issue'}]
    },
    {
     name: 'name3',
     team: 'team3',
     statuses: [{ time: 'day1', color: 'orange', message: 'mild concern'}, { time: 'day2', color: 'orange', message: 'potential issue'}]
    },
    {
     name: 'name4',
     team: 'team4',
     statuses: [{ time: 'day1', color: 'yellow', message: 'mild concern'}, { time: 'day2', color: 'green', message: 'potential issue'}]
    }
    ];

const COLORS = ['red', 'orange', 'yellow', 'green'];
const GREEN = COLORS.indexOf('green');
 
let result = list.sort((a,b) => {
    let stata = a.statuses[a.statuses.length-1];
    let statb = b.statuses[b.statuses.length-1];
    let cola = COLORS.indexOf(stata.color);
    let colb = COLORS.indexOf(statb.color);
    if (cola == GREEN && stata.message != 'looks good') {
        return (colb == GREEN && statb.message != 'looks good') ? a.name.localeCompare(b.name) : -1;
    }
    if  (colb == GREEN && statb.message != 'looks good') {
        return 1;
    }
    return (cola < colb) ? -1 : ((cola > colb) ? 1: a.name.localeCompare(b.name));
});
 
console.log(result);