Javascript - 按对象数组中的数据分组

标签 javascript arrays object ecmascript-6 group-by

我有如下的对象数组:

const obj = {
  top: [
    { id: 1, name: "Spider-man", rating: 1 },
    { id: 2, name: "Iron man", rating: 3 },
    { id: 3, name: "Hulk", rating: 5 }
  ],
  middle: [
    { id: 1, name: "Spider-man", rating: 4.5 },
    { id: 2, name: "Iron man", rating: 3.5 },
    { id: 3, name: "Hulk", rating: 1.5 }
  ],
  bottom: [
    { id: 1, name: "Spider-man", rating: 5 },
    { id: 2, name: "Iron man", rating: 2 },
    { id: 3, name: "Hulk", rating: 4 }
  ]
};

我想要的是按 id, name 分组并列出 rating 如下所示

const users = [
  {
    id: 1,
    name: "Spider-man",
    rating: {top: 1, middle: 4.5, bottom: 5}
  },
  {
    id: 2,
    name: "Iron man",
    rating: {top: 3, middle: 3.5, bottom: 2}
  },
  {
    id: 3,
    name: "Hulk",
    rating: {top: 5, middle: 1.5, bottom: 4}
  }
];

我尝试过这种方法,但似乎它可以通过更多方式实现,例如 .reducefor...of 更优雅,对吧?

const obj = {
  top: [
    { id: 1, name: "Spider-man", rating: 1 },
    { id: 2, name: "Iron man", rating: 3 },
    { id: 3, name: "Hulk", rating: 5 }
  ],
  middle: [
    { id: 1, name: "Spider-man", rating: 4.5 },
    { id: 2, name: "Iron man", rating: 3.5 },
    { id: 3, name: "Hulk", rating: 1.5 }
  ],
  bottom: [
    { id: 1, name: "Spider-man", rating: 5 },
    { id: 2, name: "Iron man", rating: 2 },
    { id: 3, name: "Hulk", rating: 4 }
  ]
};

var result = obj.top.map(x => ({
  id: x.id,
  name: x.name,
  rating: {
    top: obj.top.find(t => t.id === x.id).rating,
    middle: obj.middle.find(t => t.id === x.id).rating,
    bottom: obj.bottom.find(t => t.id === x.id).rating,
  }
}));
                          
console.log(result);

还有什么方法可以实现吗?提前致谢。

最佳答案

您需要映射其中一个子数组来找到每个 Angular 色的等级,所以我认为您当前的方法非常合理。您可以通过预先制作一个属性数组(topmiddlebot)来减少重复,然后迭代它们列出每个不同的:

const obj = {
  top: [
    { id: 1, name: "Spider-man", rating: 1 },
    { id: 2, name: "Iron man", rating: 3 },
    { id: 3, name: "Hulk", rating: 5 }
  ],
  middle: [
    { id: 1, name: "Spider-man", rating: 4.5 },
    { id: 2, name: "Iron man", rating: 3.5 },
    { id: 3, name: "Hulk", rating: 1.5 }
  ],
  bottom: [
    { id: 1, name: "Spider-man", rating: 5 },
    { id: 2, name: "Iron man", rating: 2 },
    { id: 3, name: "Hulk", rating: 4 }
  ]
};

const props = ['top', 'middle', 'bottom'];
var result = obj.top.map(x => ({
  id: x.id,
  name: x.name,
  rating: Object.fromEntries(
    props.map(prop =>
      [prop, obj[prop].find(t => t.id === x.id).rating]
    )
  )
}));      
console.log(result);

另一种计算复杂度较低的方法:

const obj = {
  top: [
    { id: 1, name: "Spider-man", rating: 1 },
    { id: 2, name: "Iron man", rating: 3 },
    { id: 3, name: "Hulk", rating: 5 }
  ],
  middle: [
    { id: 1, name: "Spider-man", rating: 4.5 },
    { id: 2, name: "Iron man", rating: 3.5 },
    { id: 3, name: "Hulk", rating: 1.5 }
  ],
  bottom: [
    { id: 1, name: "Spider-man", rating: 5 },
    { id: 2, name: "Iron man", rating: 2 },
    { id: 3, name: "Hulk", rating: 4 }
  ]
};
const byName = {};
for (const [prop, arr] of Object.entries(obj)) {
  for (const item of arr) {
    byName[item.name] ??= { ...item, rating: {} };
    byName[item.name].rating[prop] = item.rating;
  }
}
 
console.log(Object.values(byName));

关于Javascript - 按对象数组中的数据分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65930558/

相关文章:

Javascript:函数中的变量重新声明导致未定义

javascript - Sublime Text 3 中的 React.js 文件语法

java - 为什么打印 Integer array Object 给出哈希码而 char array object 在 java 中给出值?

python - 如何在循环中使用 `numpy.savez`来保存多个numpy数组?

jquery - 如何将两个数组合并为一个对象

Objective-C 判断参数是否为对象

c# - 使用 for 循环 C# 初始化数组和变量名称

javascript - 将 BASH 的日期格式转换为 JavaScript 的日期格式

javascript - TinyMCE链接插件添加自定义属性

jquery - 使用 jQuery 遍历多个 html 表