我有一个包含重复项的对象数组。 我需要在保留嵌套项目对象的同时删除重复项。
为了清楚起见,这就是我的源数组的样子:
const src = [
{
id: '5f10b85e145d7163d818066e',
name: 'Product 1',
vendor: 'Vendor 1',
instances: [
{
id: '5f10b8f6145d7163d8180672',
operatingSystem: 'Microsoft Windows 2016',
environment: 'Prod',
version: '4.0',
notes: '',
},
],
},
{
id: '5f10b856145d7163d818066d',
name: 'Product 1',
vendor: 'Vendor 2',
instances: [
{
id: '5f10b8c5145d7163d8180671',
operatingSystem: 'Microsoft Windows 2012R2',
environment: 'Prod',
version: '4.1',
notes: '',
},
],
},
{
id: '5f10b85e145d7163d818066e',
name: 'Product 1',
vendor: 'Vendor 1',
instances: [
{
id: '5f10b8f6145d7163d8180672',
operatingSystem: 'Microsoft Windows 2016',
environment: 'Prod',
version: '4.0',
notes: '',
},
],
},
];
Product 1
中的 Vendor 1
(具有相同的id
)是重复的。
我需要将重复项的实例与第一项合并。
结果数组应如下所示:
const target = [
{
id: '5f10b85e145d7163d818066e',
name: 'Product 1',
vendor: 'Vendor 1',
instances: [
{
id: '5f10b8f6145d7163d8180672',
operatingSystem: 'Microsoft Windows 2016',
environment: 'Prod',
version: '4.0',
notes: '',
},
{
id: '5f10b8f6145d7163d8180672',
operatingSystem: 'Microsoft Windows 2016',
environment: 'Prod',
version: '4.0',
notes: '',
},
],
},
{
id: '5f10b856145d7163d818066d',
name: 'Product 1',
vendor: 'Vendor 2',
instances: [
{
id: '5f10b8c5145d7163d8180671',
operatingSystem: 'Microsoft Windows 2012R2',
environment: 'Prod',
version: '4.1',
notes: '',
},
],
},
];
答案 0 :(得分:1)
您可以使用Map保留ID和对象的首次出现。
然后使用filter函数检查是否已添加ID。
const src = [
{ id: 'foo', name: 'Product 1', instances: [{ key: 'value a' }] },
{ id: 'bar', name: 'Product 2', instances: [{ key: 'value b' }] },
{ id: 'foo', name: 'Product 1', instances: [{ key: 'value c' }] }
];
const unique = new Map();
const target = src.filter((product) => {
if (unique.has(product.id)) {
unique.get(product.id).instances.push(...product.instances);
return false;
}
unique.set(product.id, product);
return true;
});
console.log(target);
答案 1 :(得分:1)
您可以使用Array.prototype.reduce()
遍历源数组并建立Map
,其中id
被用作键,因此一旦复制id
,就可以推送实例将当前对象的“对象”放入现有条目,否则设置新条目。 Map
准备就绪后,您只需使用Map.prototype.values()
提取其值:
const src = [{id:'5f10b85e145d7163d818066e',name:'Product 1',vendor:'Vendor 1',instances:[{id:'5f10b8f6145d7163d8180672',operatingSystem:'Microsoft Windows 2016',environment:'Prod',version:'4.0',notes:'',},],},{id:'5f10b856145d7163d818066d',name:'Product 1',vendor:'Vendor 2',instances:[{id:'5f10b8c5145d7163d8180671',operatingSystem:'Microsoft Windows 2012R2',environment:'Prod',version:'4.1',notes:'',},],},{id:'5f10b85e145d7163d818066e',name:'Product 1',vendor:'Vendor 1',instances:[{id:'5f10b8f6145d7163d8180672',operatingSystem:'Microsoft Windows 2016',environment:'Prod',version:'4.0',notes:'',},],},],
result = [...src
.reduce((r, o) => {
const dupe = r.get(o.id)
dupe ?
dupe.instances.push(...o.instances) :
r.set(o.id, o)
return r
}, new Map())
.values()
]
console.log(result)
.as-console-wrapper{min-height:100%;}
答案 2 :(得分:1)
有很多解决方法。这是一个。
const src = [{
id: '5f10b85e145d7163d818066e',
name: 'Product 1',
vendor: 'Vendor 1',
instances: [{
id: '5f10b8f6145d7163d8180672',
operatingSystem: 'Microsoft Windows 2016',
environment: 'Prod',
version: '4.0',
notes: '',
}, ],
},
{
id: '5f10b856145d7163d818066d',
name: 'Product 1',
vendor: 'Vendor 2',
instances: [{
id: '5f10b8c5145d7163d8180671',
operatingSystem: 'Microsoft Windows 2012R2',
environment: 'Prod',
version: '4.1',
notes: '',
}, ],
},
{
id: '5f10b85e145d7163d818066e',
name: 'Product 1',
vendor: 'Vendor 1',
instances: [{
id: '5f10b8f6145d7163d8180672',
operatingSystem: 'Microsoft Windows 2016',
environment: 'Prod',
version: '4.0',
notes: '',
}, ],
},
];
function deDupe(input) {
let result = [];
let productMap = {};
input.forEach((product, idx) => {
if (!productMap[product.id]) {
productMap[product.id] = input[idx];
} else {
productMap[product.id].instances.push(...input[idx].instances);
}
});
return Object.values(productMap)
}
console.log(deDupe(src));
答案 3 :(得分:1)
您可以使用reduce
,然后用Object.values
包装响应,以删除由reduce添加的键
const src = [ { id: '5f10b85e145d7163d818066e', name: 'Product 1', vendor: 'Vendor 1', instances: [ { id: '5f10b8f6145d7163d8180672', operatingSystem: 'Microsoft Windows 2016', environment: 'Prod', version: '4.0', notes: '', }, ], }, { id: '5f10b856145d7163d818066d', name: 'Product 1', vendor: 'Vendor 2', instances: [ { id: '5f10b8c5145d7163d8180671', operatingSystem: 'Microsoft Windows 2012R2', environment: 'Prod', version: '4.1', notes: '', }, ], }, { id: '5f10b85e145d7163d818066e', name: 'Product 1', vendor: 'Vendor 1', instances: [ { id: '5f10b8f6145d7163d8180672', operatingSystem: 'Microsoft Windows 2016', environment: 'Prod', version: '4.0', notes: '', }, ], }, ];
var res=src.reduce((a,c)=>{
if (!a[c.id]) a[c.id]= {...a[c.id],...c}
else {
a[c.id].instances.push(c.instances)
a[c.id].instances=[].concat(...a[c.id].instances);
}
return a
},{})
console.log(Object.values(res))
答案 4 :(得分:0)
使用从id
到类似这样的对象的映射:
const map = {}
...
// Given object:
if (object.id in map) {
const object_master = map[object.id]
object_master.instances.push(...object.instances)
} else map[object.id] = object