Here's my input {field1: {field2:'123', field3:{field4:'123'}}}
The goal is {field1: {update: {field2:'123', field3: {update: {field4:'123'}}
Here's what I have tried
function updateDictHelper(obj) {
Object.entries(obj).reduce((updateClause = {}, [key, value]) => {
if (typeof value !== 'object') {
return {... updateClause, [key]: value}
} else {
return {... updateClause, [key]: {update: updateDictHelper(value)}}
}
})
}
However, I can get it to work no matter what. I am quite new to java/typescript and would really appreciate any help.
You have two issues, the first is that your updateDirectHelper
doesn't return
anything. While you have a return
inside of this function, it's actually nested inside of the reduce
's callback function (updateClause, [key, value]) => {
, not the updateDictHelper
itself.
Your other issue is how you're providing a default value for acc
. Reduce natively supports an optional second argument which will act as the initial value for acc
.
reduce(callbackFn, initialValue)
It is best practice to always provide one if you can. If you don't include it, .reduce()
will essentially skip the first invocation of the callback and begin by calling the callback function with acc
set to the first value in your array, and the second argument to the second value in your array. If your array only has one value, such as in your case, then that single value is what is returned from the .reduce()
call, and your callback function for .reduce()
is never invoked:
const arrayWithOneElement = [1];
const res = arrayWithOneElement.reduce(() => {
console.log("I never run");
}); // Notice no second argument
console.log(res);
To avoid all of this, you can instead pass a second argument as an empty object, which will be the starting value of acc
:
function updateDictHelper(obj) {
return Object.entries(obj).reduce((updateClause, [key, value]) => {
if (typeof value !== 'object') {
return {...updateClause, [key]: value}
} else {
return {...updateClause, [key]: {update: updateDictHelper(value)}}
}
}, {});
}
console.log(updateDictHelper({field1: {field2:'123', field3:{field4:'123'}}}));
I would personally do this with a newer method, Object.fromEntiries(), which will build the object for you. Saves you having to worry about dealing with .reduce()
with this approach:
function updateDictHelper(obj) {
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [
key,
Object(value) === value ? {update: updateDictHelper(value)} : value
]));
}
console.log(updateDictHelper({field1: {field2:'123', field3:{field4:'123'}}}));