I have an object that can have multiple levels of nested objects/arrays, values. I need to be able to loop through it, and transform it. For example
{
arrayExample: [{
_type: 0,
value: 5
}, [{
_type: 0,
value: 1.1
}, {
_type: 0,
value: 1.2
}], {
_type: 1,
value: "hello"
}],
simpleVal: {
_type: 0,
value: 10
}
}
should become
{
arrayExample: [5, [1.1, 1.2], new customClass("hello")],
simpleVal: 10
}
The _type
just tells me if I need to parse the value with some custom class or not. If it's 0 I just use the value as it is, and if it's not I use a custom class according to the type number.
Preferably I need an iterative solution to avoid stack overflow.
I tried using this solution as a base because it's iterative, but I'm failing to construct the resulting object correctly.
EDIT
Nina's solution almost works, but it fails with objects/nested objects. Example, the following object
const obj2 = {
a: {
value: 5,
_type: 0
},
b: {
nested: {
value: "foo",
_type: 0
},
arr : [
{
value: 1,
_type: 0
},
{
value: 2,
_type: 0
},
]
}
}
returns
{
a: 5,
b: undefined
}
when it should return
{
a: 5,
b: {
nested: "foo",
arr: [1, 2]
}
}
EDIT
My question was closed, but I was able to find the answer because of Nina's initial solution. If the question can be reopened so I can post the answer I'd appreciate it. I will leave it here for now. It just needs to be changed to
function objMap(obj, func) {
return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, func(v)]));
}
const getValue = v => Array.isArray(v) ? v.map(getValue) : typeof v === 'object' && v._type === undefined ? objMap(v, getValue) :getTyped(v);
const result = Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, getValue(v)]));
By having a mapping function for objects similar to the map array function, Nina's solution works for nested objects/arrays as well. I don't think this is a duplicate question at all...but oh well.
EDIT
Nina's final solution works and is way cleaner.
For a mixed data structure you need to check if you got
class CustomClass {
constructor(value) {
this.value = value;
}
}
const
data0 = { arrayExample: [{ _type: 0, value: 5 }, [{ _type: 0, value: 1.1 }, { _type: 0, value: 1.2 }], { _type: 1, value: "hello" }], simpleVal: { _type: 0, value: 10 } },
data1 = { a: { value: 5, _type: 0 }, b: { nested: { value: "foo", _type: 0 }, arr : [{ value: 1, _type: 0 }, { value: 2, _type: 0 }] } },
isTyped = o => '_type' in o && 'value' in o,
getTyped = ({ _type, value }) => {
switch (_type) {
case 0: return value;
case 1: return new CustomClass(value);
}
},
getValue = data => Array.isArray(data)
? data.map(getValue)
: isTyped(data)
? getTyped(data)
: Object.fromEntries(Object
.entries(data)
.map(([k, v]) => [k, getValue(v)])
);
console.log(getValue(data0));
console.log(getValue(data1));
.as-console-wrapper { max-height: 100% !important; top: 0; }