I have this nested Object:
{
1: { one: { a: 5, b: 6, c: 7, d: 8 } },
2: { one: { a: 6, b: 9, c: 10, d: 12, e: 1 } },
3: { one: { a: 3, b: 4, c: 9 } },
}
Required output:
{
one: {
a: [5, 6, 3]
b: [6, 9, 4]
c: [7, 10, 9]
d: [12]
e: [1]
}
}
Tried nested queries but failed.
CodePudding user response:
Here's my take. A series of nested for for...in
loops. Tried to optimize for readability.
const object = {
1: { one: { a: 5, b: 6, c: 7, d: 8 } },
2: { one: { a: 6, b: 9, c: 10, d: 12, e: 1 } },
3: { one: { a: 3, b: 4, c: 9 } },
};
const result = {};
for (const group in object) {
for (const num in object[group]) {
if (!result[num]) {
result[num] = {};
}
for (const letter in object[group][num]) {
if (!result[num][letter]) {
result[num][letter] = [];
}
result[num][letter].push(object[group][num][letter])
}
}
}
console.log(result)
CodePudding user response:
Use nested loops. You don't care about the keys of the top-level object, so loop over its values with Object.values()
. Then loop over the keys and values of the nested objects. Create nested objects in the result when needed, then add the values.
const obj1 = {
1: {one:{ a:5,b:6,c:7,d:8}},
2: {one:{ a:6,b:9,c:10,d:12,e:1}},
3: {one:{a:3,b:4,c:9}}
};
let result = {};
Object.values(obj1).forEach(val1 => {
Object.entries(val1).forEach(([key2, val2]) => {
if (!result.hasOwnProperty(key2)) {
result[key2] = {};
}
res2 = result[key2];
Object.entries(val2).forEach(([key3, val3]) => {
if (!res2.hasOwnProperty(key3)) {
res2[key3] = [val3];
} else {
res2[key3].push(val3);
}
});
});
});
console.log(result);
CodePudding user response:
My approach is doing two groups:
- group the first top-level object
keys
and get their values store them as value of an array. - group the keys of the arrays value (in the previous group)
let objs = {
1: { one: { a: 5, b: 6, c: 7, d: 8 } },
2: { one: { a: 6, b: 9, c: 10, d: 12, e: 1 } },
3: { one: { a: 3, b: 4, c: 9 } },
};
let groupByKey = {};
for (const obj of Object.values(objs)) {
let [key, inerObjs] = Object.entries(obj)[0];
groupByKey[key] ??= [];
groupByKey[key].push(Object.entries(inerObjs));
}
let result = {};
for (const [k, arrs] of Object.entries(groupByKey)) {
let group = {};
for (const obj of arrs.flat()) {
if (!group.hasOwnProperty(obj[0])) {
group[obj[0]] = [obj[1]];
} else {
group[obj[0]].push(obj[1]);
}
}
result[k] = group;
}
console.log(result);
CodePudding user response:
Here is a recursive option that works for objects of arbitrary depth. Here calling it in a for...of
loop over the Object.values
of your input in order to skip the top level properties as per your expected output.
function groupProperties(obj, res = {}) {
for (const [k, v] of Object.entries(obj)) {
if (typeof v === 'object') {
groupProperties(v, (res[k] ??= {}));
}
else {
(res[k] ??= []).push(v);
}
}
return res;
}
const input = { 1: { one: { a: 5, b: 6, c: 7, d: 8 } }, 2: { one: { a: 6, b: 9, c: 10, d: 12, e: 1 } }, 3: { one: { a: 3, b: 4, c: 9 } }, };
const result = {};
for (const obj of Object.values(input)) {
groupProperties(obj, result);
}
console.log(result);