我有以下对象:
[{animal: 1, hasLegs: true},{animal: 1, hasTail: false},
{animal: 2, hasLegs: true},{animal: 2, hasTail: true},{animal: 3}]
我想将其重组为以下内容:
[
{ animal:1, info: { hasLegs: true, hasTail: false },
{ animal:2, info: { hasLegs: true, hasTail: true },
{ animal:3, into: {},
]
使得具有animal:1
的数组中的所有对象统一在该键下,并在键info
下将其余键与值相加。
曾经尝试使用map()
函数但无法掌握其功能,并且不知道单独使用map()
是否可以解决此问题。
答案 0 :(得分:2)
这是一个相似的答案,但应具有更好的性能,因为它利用了映射哈希的优势,而不是对每个条目进行查找。
const data = [{animal: 1, hasLegs: true},{animal: 1, hasTail: false},
{animal: 2, hasLegs: true},{animal: 2, hasTail: true},{animal: 3}]
const infoMap = data.reduce((rollup, { animal, ...info }) => {
const entry = rollup[animal] = rollup[animal] || {}
Object.assign(entry, info)
return rollup
}, {})
const result = Object.keys(infoMap)
.map((animal) => ({
animal,
info: infoMap[animal]
}))
console.log(result)
答案 1 :(得分:2)
我建议从初始数组创建一个查找对象。这样,您无需遍历每个元素上的整个数组(这将使它O(n²)
)。
所以预先给出了我们的列表:
const animals = [
{ animal: 1, hasLegs: true },
{ animal: 1, hasTail: false },
{ animal: 2, hasLegs: true },
{ animal: 2, hasTail: true },
{ animal: 3 }
]
我们用reduce
创建一个查找表,将在原始数组中找到的每个对象合并到动物的value对象中:
const lookup = animals.reduce((acc, val) => {
// use object destructuring and object spread to pick out
// the "animal" field and the rest into separate variables
const { animal, ...info } = val
// get existing info object, or create new empty if not found
const existingInfo = acc[animal] || {}
// merge existing info and new info from this object
acc[animal] = { ...existingInfo, ...info }
return acc
}, {})
此时,结构如下:
{
'1': { hasLegs: true, hasTail: false },
'2': { hasLegs: true, hasTail: true },
'3': {}
}
现在,我们只需要遍历此对象并将其转换为数组,然后将键选择到“动物”字段中即可:
const after = Object.entries(lookup).map(([key, value]) => {
return { animal: key, info: value }
})
这将产生我们想要的结果:
[
{ animal: '1', info: { hasLegs: true, hasTail: false } },
{ animal: '2', info: { hasLegs: true, hasTail: true } },
{ animal: '3', info: {} }
]
请注意,尽管较旧的浏览器可能不支持Object.entries
。如果您定位的是较旧的浏览器,请在Object.keys
答案 2 :(得分:1)
const array = [{ animal: 1, hasLegs: true }, { animal: 1, hasTail: false },
{ animal: 2, hasLegs: true }, { animal: 2, hasTail: true }, { animal: 3 }];
const result = [];
array.forEach(obj => {
let newEntry = null;
if (result.findIndex(entry => entry.animal === obj.animal) === -1) {
newEntry = { animal: obj.animal, info: {} }
result.push(newEntry);
}
const entry = newEntry || result.find(entry => entry.animal === obj.animal);
Object.keys(obj).forEach(key => {
if (key === 'animal') return;
entry.info[key] = obj[key];
});
});
console.log(result);