[英]Merge array of objects within array of objects
我有以下對象
Person {
name: string
birthday: Date
lifeEvents: LifeEvent[]
}
LifeEvent {
eventId: number
message: string
comments: string
}
由於數據以塊的形式出現,我將有一個Person
數組,其中一個對象具有name
和birthday
以及值,但lifeEvents
是空的(將此視為父對象。)
所有其他對象都不會填充生日和姓名,並且只有一個LifeEvent
帶有eventId
和帶有值的message
或eventId
和comments
在該數組中,我需要獲取具有名稱和生日的父對象,然后從其余對象中獲取所有 lifeEvents,將包含相同 eventId 的所有項目合並到LifeEvent
中,然后將其推送到父對象的 lifeEvents。
我已經嘗試過 array.reduce、array.map 但無法找到將這些對象組合成一個的方法。
我的輸出應該只有一個Person
,所有lifeEvents
都由eventId
合並
樣本數據:
let results = [
{
name: 'Test1',
birthday: '2022-06-14',
lifeEvents: null
},
{
name: null,
birthday: null,
lifeEvents: [
{
eventId: 1,
message: 'First event',
comments: null
}
]
},
{
name: null,
birthday: null,
lifeEvents: [
{
eventId: 2,
message: 'Second event',
comments: null
}
]
},
{
name: null
birthday: null
lifeEvents: [
{
eventId: 1,
message: null,
comments: 'First event comment'
}
]
},
{
name: null
birthday: null
lifeEvents: [
{
eventId: 2,
message: null,
comments: 'Second event comment'
}
]
},
]
感謝任何幫助。
以下根據提供的示例生成請求的結果:
let results = [ { name: 'Test1', birthday: '2022-06-14', lifeEvents: null }, { name: null, birthday: null, lifeEvents: [ { eventId: 1, message: 'First event', comments: null } ] }, { name: null, birthday: null, lifeEvents: [ { eventId: 2, message: 'Second event', comments: null } ] }, { name: null, birthday: null, lifeEvents: [ { eventId: 1, message: null, comments: 'First event comment' } ] }, { name: null, birthday: null, lifeEvents: [ { eventId: 2, message: null, comments: 'Second event comment' } ] }, ]; // extract parent const parentResult = results.find((result) => result.name); // generate unique events from sibling entities const uniqueEvents = new Map(); results.forEach((result) => result.lifeEvents?.forEach( (lifeEvent) => { if (uniqueEvents.has(lifeEvent.eventId)) { updateEvent(lifeEvent); } else { uniqueEvents.set(lifeEvent.eventId, { eventId: lifeEvent.eventId, message: lifeEvent.message, comments: lifeEvent.comments}); } }) ); // function to update event that is already stored in uniqueEvents function updateEvent(lifeEvent) { const existingLifeEvent = uniqueEvents.get(lifeEvent.eventId); if (lifeEvent.message) existingLifeEvent.message = lifeEvent.message; if (lifeEvent.comments) { if (existingLifeEvent.comments) { existingLifeEvent.comments.concat(lifeEvent.comments) } else { existingLifeEvent.comments = lifeEvent.comments; } } } // populate lifeEvents inside the parentResult parentResult.lifeEvents = []; uniqueEvents.forEach((uniqueId) => { parentResult.lifeEvents.push(uniqueId); }); console.log(parentResult);
前提:您使用的數據結構是錯誤的,您應該嘗試使用具有同質模型的數組。
也就是說,我使用了一種 reduce 方法,條件是以與其他元素不同的方式處理第一個元素。
最后一件事,你說合並lifeEvents,我假設你的意思是覆蓋具有相同 id 的事件的無效值,如果你想覆蓋所有值,那么你可以省略我寫的合並實用程序函數。
let results = [{ name: 'Test1', birthday: '2022-06-14', lifeEvents: null, }, { name: null, birthday: null, lifeEvents: [{ eventId: 1, message: 'First event', comments: null, }, ], }, { name: null, birthday: null, lifeEvents: [{ eventId: 2, message: 'Second event', comments: null, }, ], }, { name: null, birthday: null, lifeEvents: [{ eventId: 1, message: null, comments: 'First event comment', }, ], }, { name: null, birthday: null, lifeEvents: [{ eventId: 2, message: null, comments: 'Second event comment', }, ], }, ]; const merge = (o1, o2) => { const r = {...o1} Object.keys(o1).forEach(k => r[k] = o2[k] || o1[k]) return r } const r = results.reduce((o, curr, i) => { if (i === 0) { return { ...o, lifeEvents: [] }; } else { const currentEvent = curr.lifeEvents[0] const idx = o.lifeEvents.findIndex((_o) => _o.eventId === currentEvent.eventId); if (idx !== -1) return { ...o, lifeEvents: o.lifeEvents.map((_o, i) => i === idx ? merge(_o, currentEvent) : _o) } else return { ...o, lifeEvents: [...o.lifeEvents, currentEvent] } } }, results[0]); console.log("RESULT:", r);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.