javascript - 使用 Javascript 操作对象并合并相似数据
问题描述
我正在努力处理 Javascript 对象,并感谢您的建议:
我有以下对象:
const source = {
id: '1',
name: 'Customer A',
projects: [
{
id: '10',
name: 'Project 2',
description: 'Project 2 description',
products: [
{
id: '100',
name: 'Product 1',
vendor: 'Vendor 1',
instances: [
{
id: '1000',
operatingSystem: 'Microsoft Windows 2012R2',
environment: 'Prod',
version: '4.1',
notes: '',
},
],
},
{
id: '200',
name: 'Product 2',
vendor: 'Vendor 2',
instances: [
{
id: '2000',
operatingSystem: 'Microsoft Windows 2016',
environment: 'Prod',
version: '4.0',
notes: '',
},
],
},
],
},
{
id: '20',
name: 'Project 1',
description: 'Project 1 description',
products: [
{
id: '200',
name: 'Product 2',
vendor: 'Vendor 2',
instances: [
{
id: '2000',
operatingSystem: 'Microsoft Windows 2016',
environment: 'Prod',
version: '4.0',
notes: '',
},
{
id: '3000',
operatingSystem: 'RedHat Linux 7',
environment: 'Prod',
version: '3.12',
notes: '',
},
],
},
],
},
],
};
我想从上面的对象中提取按产品分组的实例列表(这部分工作正常):
const products = [
{
id: '100',
name: 'Product 1',
vendor: 'Vendor 1',
instances: [
{
id: '1000',
operatingSystem: 'Microsoft Windows 2012R2',
environment: 'Prod',
version: '4.1',
notes: '',
},
],
},
{
id: '200',
name: 'Product 2',
vendor: 'Vendor 2',
instances: [
{
id: '2000',
operatingSystem: 'Microsoft Windows 2016',
environment: 'Prod',
version: '4.0',
notes: '',
},
{
id: '2000',
operatingSystem: 'Microsoft Windows 2016',
environment: 'Prod',
version: '4.0',
notes: '',
},
{
id: '3000',
operatingSystem: 'RedHat Linux 7',
environment: 'Prod',
version: '3.12',
notes: '',
},
],
},
];
以上是通过映射项目、扁平化产品阵列和减少结果来实现的。我的下一个目标是为每个实例添加与其关联的项目。我需要附上项目 ID 和项目名称。在上面的示例中,您可以看到具有 '2000' id 的实例与 2 个项目相关联,因此,预期结果应如下所示:
const expected = [
{
id: '100',
name: 'Product 1',
vendor: 'Vendor 1',
instances: [
{
id: '1000',
operatingSystem: 'Microsoft Windows 2012R2',
environment: 'Prod',
version: '4.1',
notes: '',
projects: [
{
id: '10',
name: 'Project 2',
},
],
},
],
},
{
id: '200',
name: 'Product 2',
vendor: 'Vendor 2',
instances: [
{
id: '2000',
operatingSystem: 'Microsoft Windows 2016',
environment: 'Prod',
version: '4.0',
notes: '',
projects: [
{
id: '10',
name: 'Project 2',
},
{
id: '20',
name: 'Project 1',
},
],
},
{
id: '3000',
operatingSystem: 'RedHat Linux 7',
environment: 'Prod',
version: '3.12',
notes: '',
projects: [
{
id: '20',
name: 'Project 1',
},
],
},
],
},
];
我试图通过几个“forEach”循环、映射等来操作数组,但没有成功。希望您能提出如何实现的想法。
解决方案
const { inspect } = require('util'); // if Node.js
const source = {
id: '1', name: 'Customer A', projects: [
{
id: '10', name: 'Project 2', description: 'Project 2 description', products: [
{
id: '100', name: 'Product 1', vendor: 'Vendor 1', instances: [
{ id: '1000', operatingSystem: 'Microsoft Windows 2012R2', environment: 'Prod', version: '4.1', notes: '', },
],
},
{
id: '200', name: 'Product 2', vendor: 'Vendor 2', instances: [
{ id: '2000', operatingSystem: 'Microsoft Windows 2016', environment: 'Prod', version: '4.0', notes: '', },
],
},
],
},
{
id: '20', name: 'Project 1', description: 'Project 1 description', products: [
{
id: '200', name: 'Product 2', vendor: 'Vendor 2', instances: [
{ id: '2000', operatingSystem: 'Microsoft Windows 2016', environment: 'Prod', version: '4.0', notes: '', },
{ id: '3000', operatingSystem: 'RedHat Linux 7', environment: 'Prod', version: '3.12', notes: '', },
],
},
],
},
],
};
const projectToIdMap = source.projects.reduce((projectToIdMap, { name, products }) => {
projectToIdMap[name] = [];
products.forEach(({ instances }) => {
instances.forEach(({ id }) => {
projectToIdMap[name].push(id);
});
});
return projectToIdMap;
}, {});
const products = [
{
id: '100', name: 'Product 1', vendor: 'Vendor 1', instances: [
{ id: '1000', operatingSystem: 'Microsoft Windows 2012R2', environment: 'Prod', version: '4.1', notes: '', },
],
},
{
id: '200', name: 'Product 2', vendor: 'Vendor 2', instances: [
{ id: '2000', operatingSystem: 'Microsoft Windows 2016', environment: 'Prod', version: '4.0', notes: '', },
{ id: '2000', operatingSystem: 'Microsoft Windows 2016', environment: 'Prod', version: '4.0', notes: '', },
{ id: '3000', operatingSystem: 'RedHat Linux 7', environment: 'Prod', version: '3.12', notes: '', },
],
},
];
products.forEach(({ instances }) => {
instances.forEach(instance => {
instance.projects = [];
const { id } = instance;
Object.entries(projectToIdMap).forEach(([project, os], i) => {
if (projectToIdMap[project].includes(id)) {
instance.projects.push({ id: (i + 1) * 10, project });
}
});
});
});
console.log(inspect(products, false, null, true)); // if Node.js
这不会删除重复的Microsoft Windows 2016
条目,但我相信您可以从这里获取它。
推荐阅读
- google-sheets - Google表格公式 - 对一行数字数据进行排序
- sql - 时序数据查询——优化查询性能
- python - 为什么 python 的 numba 在 Spyder 上运行 2D 数组程序而不在远程服务器上运行?
- filter - 具有多个条件的过滤器功能,包括空白单元格
- google-cloud-platform - 授予对 GCP 存储桶中对象(csv 文件)的访问权限
- python - 应用 pd.to_datetime 时日期变得疯狂
- image - 使用 Drupal 7 的非开发营销人员无法将图像添加到我们的主页 - 仅在将图像上传到媒体浏览器后显示代码
- powerbi - 通过 webhook 获取数据
- python - 如何在 homedepot 中抓取期权组合价格
- keras - 批量标准化时如何应用 L2?