扁平化,对象数组并返回唯一数组



我有一个像这样的数组。

var arr = [{
"taxname": "MFM",
"member": [{
"id": 1334,
"name": "Mary G. King",
}, {
"id": 1324,
"name": "Bonnie A. Wilson",
}, {
"id": 1336,
"name": "Samantha B. Sellers",
}]
},
{
"taxname": "Test purpose",
"member": [{
"id": 1336,
"name": "Samantha B. Sellers",
}]
},
{
"taxname": "New_Test_MF",
"member": [{
"id": 1334,
"name": "Mary G. King",
}]
}
];

我已经把它弄平了,所以它只是一个对象数组。

const result = arr.reduce((r, obj) => r.concat(obj.member), []);

结果:

[{
id: 1334,
name: "Mary G. King"
}, {
id: 1324,
name: "Bonnie A. Wilson"
}, {
id: 1336,
name: "Samantha B. Sellers"
}, {
id: 1336,
name: "Samantha B. Sellers"
}, {
id: 1334,
name: "Mary G. King"
}]

然后从结果中删除带有id的重复,I did.

const ids = result.map(o => o.id)
const filtered = result.filter(({id}, index) => !ids.includes(id, index + 1))

记录结果:

console.log(filtered);
[{
id: 1324,
name: "Bonnie A. Wilson"
}, {
id: 1336,
name: "Samantha B. Sellers"
}, {
id: 1334,
name: "Mary G. King"
}]
我已经得到了我想要的结果。但是,平坦化对象数组并返回唯一数组而不是使用多个查询的最佳方法是什么?

我认为你的方法还不错,而且代码可读性很强!有时候并不是要写出高性能的代码,而是要写出易读、易维护和可扩展的代码!

也就是说,这里有一些其他的选择:

  1. 你可以结合你的步骤,同时减少使用映射来存储id作为键,以便更快地查找(而不是检查id数组)。
const existingIds = {};
const result = arr.reduce((r, obj) => r.concat(obj.member.filter((m) => {
if (existingIds.hasOwnProperty(m.id.toString())) {
return false;
}
existingIds[m.id] = true;
return true;
})), []);
  1. 使用集合的力量(没有重复的元素)!

作为对代码的一个小修改,您可以使用Set来存储不重复的id。这样,在最后一步中,您不必执行include操作,而是执行find操作,尽管您在这里的交易并不多。

const array2 = arr.reduce((r, obj) => r.concat(obj.member), []);
const nonDuplicateIds = Array.from(new Set(array2.map(m => m.id)))
const result2 = nonDuplicateIds.map(id => array2.find(member => member.id === id)) // You could also use an object for faster lookup
  1. 可能是我最喜欢的:使用对象使你的代码更简单,不需要任何映射/过滤!
const members = {};
arr.forEach(data => data.member.forEach((member) => members[member.id] = member));
const result3 = Object.values(members);
  1. 编辑:一个快速,低效的一行,您可以在减少的同时检查重复的元素!
const result4 = arr.reduce((r, obj) => r.concat(obj.member.filter((m) => r.every(existingM => existingM.id !== m.id))), []);

var arr = [{
"taxname": "MFM",
"member": [{
"id": 1334,
"name": "Mary G. King",
}, {
"id": 1324,
"name": "Bonnie A. Wilson",
}, {
"id": 1336,
"name": "Samantha B. Sellers",
}]
},
{
"taxname": "Test purpose",
"member": [{
"id": 1336,
"name": "Samantha B. Sellers",
}]
},
{
"taxname": "New_Test_MF",
"member": [{
"id": 1334,
"name": "Mary G. King",
}]
}
];
// Alternative #1
const existingIds = {};
const result = arr.reduce((r, obj) => r.concat(obj.member.filter((m) => {
if (existingIds.hasOwnProperty(m.id.toString())) {
return false;
}
existingIds[m.id] = true;
return true;
})), []);
// Alternative #2
const array2 = arr.reduce((r, obj) => r.concat(obj.member), []);
const nonDuplicateIds = Array.from(new Set(array2.map(m => m.id)))
const result2 = nonDuplicateIds.map(id => array2.find(member => member.id === id)) // You could also use an object for faster lookup
// Alternative #3
const members = {};
arr.forEach(data => data.member.forEach((member) => members[member.id] = member));
const result3 = Object.values(members);
// Alternative #4
const result4 = arr.reduce((r, obj) => r.concat(obj.member.filter((m) => r.every(existingM => existingM.id !== m.id))), []);
console.log(result.length);
console.log(result2.length);
console.log(result3.length);
console.log(result4.length);

您可以在ES10中使用flat函数

var arr = [{
"taxname": "MFM",
"member": [{
"id": 1334,
"name": "Mary G. King",
}, {
"id": 1324,
"name": "Bonnie A. Wilson",
}, {
"id": 1336,
"name": "Samantha B. Sellers",
}]
},
{
"taxname": "Test purpose",
"member": [{
"id": 1336,
"name": "Samantha B. Sellers",
}]
},
{
"taxname": "New_Test_MF",
"member": [{
"id": 1334,
"name": "Mary G. King",
}]
}
];
var test = arr.map(a => a.member).flat();
var filterd = [...new Set(test.map(t=>t.id))].map(id => test.find(tt => tt.id === id));
console.log(filterd)

最新更新