Я бы предложил создать объект поиска из исходного массива. Таким образом, вам не нужно просматривать весь массив на каждом элементе (что делает его O(n²)
).
Итак, заранее учитывая наш список:
const animals = [
{ animal: 1, hasLegs: true },
{ animal: 1, hasTail: false },
{ animal: 2, hasLegs: true },
{ animal: 2, hasTail: true },
{ animal: 3 }
]
Мы создаемтаблица поиска с reduce
, объединяющая каждый объект, который мы находим в исходном массиве, в объект значения животного:
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