[英]Group array objects so that objects with similar key are not put into the same group
[英]How to group by an array of objects with similar names but not the same
我有這種類型的對象數組:
[{
ID: 'MCHARPENT ',
REA: 4,
STO: 90,
EFFCAR: 178,
},
{
ID: 'I050MCHE ',
REA: 0,
STO: 125,
EFFCAR: 228,
},
{
ID: 'I050MCHE ',
REA: 0,
STO: 106,
EFFCAR: 231,
},
{
ID: 'DBALLAVOINE',
REA: 0,
STO: 107,
EFFCAR: 172,
},
{
ID: 'DBALLAVOINE',
REA: 20,
STO: 30,
EFFCAR: 100,
}]
當 ID 為:
如果匹配,則不帶“I050”的 ID 將取代名稱。 此外,我必須對其他值求和。
使用這四個對象的結果應該如下所示:
{
ID: 'MCHARPENT',
REA: 4,
STO: 321,
EFFCAR: 637,
},
{
ID: 'DBALLAVOINE',
REA: 20,
STO: 137,
EFFCAR: 272,
}]
我無法找到一種方法來滿足這些條件。
沒有進行任何排序,因為幸運的是給定的示例不需要它。 這可能是一個問題,具體取決於您獲得的數據數組。
let results = []; let something = 'I050'; let items = [{ID: 'MCHARPENT ',REA: 4,STO: 90,EFFCAR: 178,},{ID: 'I050MCHE ',REA: 0,STO: 125,EFFCAR: 228,},{ID: 'I050MCHE ',REA: 0,STO: 106,EFFCAR: 231,},{ID: 'DBALLAVOINE',REA: 0,STO: 107,EFFCAR: 172,}]; items.forEach( item => { if (item.ID.startsWith(something)) { results.filter( result => { if (result.ID.startsWith(item.ID.trim().slice(4, -1))) { result.REA = result.REA + item.REA; result.STO = result.STO + item.STO; result.EFFCAR = result.EFFCAR + item.EFFCAR; } // could do an ELSE here pushing the item to results so it doesn't get lost if there is no match }); } else { results.push(item); } }); console.log(results);
這是使用.sort()
( Documentation ) 和.reduce()
( Documentation ) 的一種方法
首先,我們對對象進行排序以將所有'I050'
ID 放在最后(因為它們可能需要折疊到我們需要首先創建的現有對象中)
然后,我們減少結果並組合符合要求的對象。
const data = [{ID: 'MCHARPENT ', REA: 4, STO: 90, EFFCAR: 178}, {ID: 'I050MCHE ', REA: 0, STO: 125, EFFCAR: 228}, { ID: 'I050MCHE ', REA: 0, STO: 106, EFFCAR: 231}, { ID: 'DBALLAVOINE', REA: 0, STO: 107, EFFCAR: 172 }] const result = data // Move all of the 'I050' IDs to the end.sort(obj => obj.ID.startsWith('I050')? 1: -1) // Combine the data.reduce((acc, curr) => { // Find any existing object we would want to merge this into const existingObj = acc.find(obj => // Has the same ID obj.ID === curr.ID || // Or, if this is an 'I050', starts with the next 3 chars (curr.ID.startsWith('I050') && obj.ID.startsWith(curr.ID.substring(4, 7)))) // If we find an object, merge them if (existingObj) { existingObj.REA += curr.REA existingObj.STO += curr.STO existingObj.EFFCAR += curr.EFFCAR } else { // If not, just add this as a new object acc.push(curr) } // Return the new array return acc }, []) console.log(result)
這里有 2 個簡單for
循環
const data = [ { ID: 'MCHARPENT ', REA: 4, STO: 90, EFFCAR: 178, }, { ID: 'I050MCHE ', REA: 0, STO: 106, EFFCAR: 231, }, { ID: 'I050MCHE ', REA: 0, STO: 125, EFFCAR: 228, }, { ID: 'DBALLAVOINE', REA: 0, STO: 107, EFFCAR: 172, }]; const groupedData = []; function canBeMerged(item1, item2){ if(item1.ID == item2.ID) return true; let item1ID = item1.ID.substring(4, 7); let item2ID = item2.ID.substring(0, 3); if(item1ID == item2ID) return true; item2ID = item2.ID.substring(4, 7); item1ID = item1.ID.substring(0, 3); if(item1ID == item2ID) return true; return false; } function merge(group, datapoint){ group.REA += datapoint.REA; group.STO += datapoint.STO; group.EFFCAR += datapoint.EFFCAR; } for(let i = 0; i < data.length; i++){ if(i === 0){ groupedData.push(data[i]); continue; } let added = false; for(let j = 0; j < groupedData.length; j++){ if(canBeMerged(groupedData[j], data[i])){ merge(groupedData[j], data[i]); added = true; continue; } } if(added === false) groupedData.push(data[i]); } console.log(groupedData)
編輯 1:添加 function 以檢查合並條件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.