I have an array of objects with the same keys, I want to create a new array of objects that creates a new object that combines the uniques ones together into one
const arrayOfObjects = [
{ 'Serial Number': '90946117350061093222581604839920' },
{ 'Serial Number': '77362117350061093222581604891733' },
{ 'Serial Number': '77362117350061093222581604891734' },
{ 'Part Number': 'TR40-60C779-AA' },
{ 'Part Number': 'ST41-60C780-AA' },
{ 'Part Number': 'QT41-60C780-AA' },
{ 'Cell Count': '28' },
{ 'Cell Count': '27' },
{ 'Cell Count': '29' },
{ 'Length': '10' },
{ 'Length': '11' },
{ 'Length': '11' },
]
So it needs to look like the below.
const desiredArrayOfObjects = [
{
'Serial Number': '90946117350061093222581604839920',
'Part Number': 'TR40-60C779-AA',
'Cell Count': '27',
'Length': '10',
},
{
'Serial Number': '77362117350061093222581604891733',
'Part Number': 'ST41-60C780-AA',
'Cell Count': '28',
'Length': '11',
},
{
'Serial Number': '77362117350061093222581604891734',
'Part Number': 'QT41-60C780-AA',
'Cell Count': '29',
'Length': '12',
},
]
I have tried it with the code below, but i'm clearly not getting it right, help is welcome and appreciated.
let newArr = [];
arrayOfObjects.map((x,i) => {
Object.entries(x).map(([key, value]) => {
if(!newArr.length){
if(Object.keys(newArr[i]).toString() === key){
newArr.push({[key]: value})
}
}
})
})
CodePudding user response:
I think it'best if you first separate them and the put it back together
const arrayOfObjects = [
{ 'Serial Number': '90946117350061093222581604839920' },
{ 'Serial Number': '77362117350061093222581604891733' },
{ 'Serial Number': '77362117350061093222581604891734' },
{ 'Part Number': 'TR40-60C779-AA' },
{ 'Part Number': 'ST41-60C780-AA' },
{ 'Part Number': 'QT41-60C780-AA' },
{ 'Cell Count': '28' },
{ 'Cell Count': '27' },
{ 'Cell Count': '29' },
{ 'Length': '10' },
{ 'Length': '11' },
{ 'Length': '11' },
]
const keys = ['Serial Number', 'Part Number', 'Cell Count', 'Length']
const separated = arrayOfObjects.reduce((res, item) => {
const key = Object.keys(item)[0]
const existing = res[key] || []
res[key] = [...existing, item[key]]
return res
}, {})
const result = separated[keys[0]].map((_, i) => {
return keys.reduce((res, k ) => {
return {...res, [k]: separated[k][i]}
}, {})
})
console.log(result)
CodePudding user response:
A solution that doesn't require knowing the properties ahead of time would be to separate the array into sub-arrays of matching property, and then map over the longest of these sub-arrays merging the contained objects into one. (This does require that all like properties be sequential in the source array.)
const arrayOfObjects = [{ 'Serial Number': '90946117350061093222581604839920' }, { 'Serial Number': '77362117350061093222581604891733' }, { 'Serial Number': '77362117350061093222581604891734' }, { 'Part Number': 'TR40-60C779-AA' }, { 'Part Number': 'ST41-60C780-AA' }, { 'Part Number': 'QT41-60C780-AA' }, { 'Cell Count': '28' }, { 'Cell Count': '27' }, { 'Cell Count': '29' }, { 'Length': '10' }, { 'Length': '11' }, { 'Length': '11' },];
const grouped = [];
let prev;
for (const obj of arrayOfObjects) {
const [key] = Object.keys(obj);
if (key !== prev) {
grouped.push([]);
}
grouped.at(-1).push(obj);
prev = key;
}
const result = grouped
.sort(({ length: a }, { length: b }) => b - a)[0]
.map((_, i) => Object.assign(...grouped.map(p => p[i] ?? {})));
console.log(result)
Or, using grouping if the order of the source array is unknown (the object the individual properties end up in will still be sensitive to the ordering of the source array)
const arrayOfObjects = [{ 'Serial Number': '90946117350061093222581604839920' }, { 'Serial Number': '77362117350061093222581604891733' }, { 'Serial Number': '77362117350061093222581604891734' }, { 'Part Number': 'TR40-60C779-AA' }, { 'Part Number': 'ST41-60C780-AA' }, { 'Part Number': 'QT41-60C780-AA' }, { 'Cell Count': '28' }, { 'Cell Count': '27' }, { 'Cell Count': '29' }, { 'Length': '10' }, { 'Length': '11' }, { 'Length': '11' },];
const grouped = {}
for (const obj of arrayOfObjects) {
const [[key, value]] = Object.entries(obj);
(grouped[key] ??= []).push(value);
}
const result = [];
for (const [key, values] of Object.entries(grouped)) {
for (const [i, value] of values.entries()) {
(result[i] ??= {})[key] = value;
}
}
console.log(result)