Reputation: 37
I want to convert data from an object tree to an array of objects of this kind
I can’t do if you can give me an algorithm or a solution to this problem. Any thought you can grab onto. My brain refuses to work.
from:
const input = {
p1: {
s1: {
title: 'scene 1',
description: 'description 1',
value: 1,
},
s2: {
title: 'scene 2',
description: 'description 2',
value: 32,
},
s3: {
title: 'scene 3',
description: 'description 3',
value: 89,
},
s4: {
title: 'scene 3',
description: 'description 3',
value: 0,
},
},
p2: {
s5: {
title: 'scene 5',
description: 'description 5',
value: 0,
},
s6: {
title: 'scene 6',
description: 'description 6',
value: 42,
},
s7: {
title: 'scene 7',
description: 'description 7',
value: -9,
},
},
}
to:
[
{ projectId: 'p1', sceneId: 's1', value: 1, title: 'scene 1' },
{ projectId: 'p1', sceneId: 's2', value: 32, title: 'scene 2' },
{ projectId: 'p1', sceneId: 's3', value: 89, title: 'scene 3' },
{ projectId: 'p2', sceneId: 's6', value: 42, title: 'scene 6' },
]
I tried to do this with Object.entries and Array.reduce with recursive function, but I can't do it two days ... :D
that's my attempts
const recursive = (obj, lvl = 0) => {
if (typeof obj !== 'object') {
}
const value = Object.entries(obj);
return value.reduce((acc, [key, value]) => {
if (typeof value !== 'object') {
return {...acc, [key]: value};
}
if (lvl === 0) {
return {...recursive(value, lvl + 1), sceneId: key };
}
}, {})
}
const transform = (data) => {
const a = Object.entries(data);
return a.reduce((acc, [key, value]) => {
return [...acc, recursive(value)];
}, [])
}
console.log(transform(input))
Please, help.
Upvotes: 2
Views: 86
Reputation: 14179
this should do the job too:
const map = (projectId, scenes) => R.reduce(
(res, [sceneId, scene]) => res.concat(
R.mergeRight(scene, { sceneId, projectId }),
),
[],
scenes,
);
const mapScenes = R.useWith(map, [
R.identity,
R.toPairs,
]);
const toArray = R.pipe(
R.toPairs,
R.map(
R.apply(mapScenes),
),
);
const data = {
p1: {
s1: {
title: 'scene 1',
description: 'description 1',
value: 1,
},
s2: {
title: 'scene 2',
description: 'description 2',
value: 32,
},
s3: {
title: 'scene 3',
description: 'description 3',
value: 89,
},
s4: {
title: 'scene 3',
description: 'description 3',
value: 0,
},
},
p2: {
s5: {
title: 'scene 5',
description: 'description 5',
value: 0,
},
s6: {
title: 'scene 6',
description: 'description 6',
value: 42,
},
s7: {
title: 'scene 7',
description: 'description 7',
value: -9,
},
},
};
console.log('result', toArray(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js" integrity="sha256-xB25ljGZ7K2VXnq087unEnoVhvTosWWtqXB4tAtZmHU=" crossorigin="anonymous"></script>
Upvotes: 1
Reputation: 177
let projects = [];
for (let project in input) {
for (let scene in input[project]) {
projects.push( { projectId: project, sceneId: scene, value: input[project][scene].value, title: input[project][scene].title })
}
}
Or something like this:
Object.keys(input).flatMap(project => {
return Object.keys(input[project]).map( scene => {
return { projectId: project, sceneId: scene, value: input[project][scene].value, title: input[project][scene].title }
});
});
Upvotes: 1
Reputation: 386570
You could take a dynamic approach by hand over the wanted keys for nested objects and the values keys for getting a flat result set.
function getFlat(object, keys, values) {
function iter(object, [key, ...keys], temp = {}) {
if (key === undefined) {
if (object.value > 0) {
result.push(values.reduce((t, k) => ({ ...t, [k]: object[k] }), temp));
}
return;
}
Object.entries(object).forEach(([k, v]) => iter(v, keys, { ...temp, [key]: k }));
}
var result = [];
iter(object, keys);
return result;
}
var input = { p1: { s1: { title: 'scene 1', description: 'description 1', value: 1 }, s2: { title: 'scene 2', description: 'description 2', value: 32 }, s3: { title: 'scene 3', description: 'description 3', value: 89 }, s4: { title: 'scene 3', description: 'description 3', value: 0 } }, p2: { s5: { title: 'scene 5', description: 'description 5', value: 0 }, s6: { title: 'scene 6', description: 'description 6', value: 42 }, s7: { title: 'scene 7', description: 'description 7', value: -9 } } },
output = getFlat(input, ['projectId', 'sceneId'], ['value', 'title']);
console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 3