While trying to become more comfortable with recursive functions, I attempted to write a function that takes a dot-separated string and converts that into an object.
So, given the following string: user.first.name.robert
this function should return the following object:
{
user: {
first: {
name: 'robert'
}
}
}
Here's my attempt:
function objectifyHelper(array, object) {
if (array.length === 2) {
const [key, value] = array;
object[key] = value;
return object;
} else {
object[array[0]] = objectifyHelper(array.slice(1), object);
return object;
}
}
function objectify(string) {
const tokens = string.split('.');
return objectifyHelper(tokens, {});
}
const str = 'user.first.name.robert';
const result = objectify(str);
This gets me the following result:
result <ref *1> {
name: 'robert',
first: [Circular * 1],
user: [Circular * 1]
}
What am I doing wrong?
CodePudding user response:
You're only ever creating a single object here:
return objectifyHelper(tokens, {});
that then gets used every time a property is assigned to it. You need to instead create a new object when recursing, and not only inside of objectify
.
A simpler approach would be:
const objectify = string => string
.split('.')
.reduceRight(
(innerObj, prop) => ({ [prop]: innerObj })
);
const str = 'user.first.name.robert';
const result = objectify(str);
console.log(result);
CodePudding user response:
You are almost there. However, if your helper accepts an object but also returns it, be consistent in your recursive call
function objectifyHelper(array, object) {
if (array.length === 2) {
const [key, value] = array;
object[key] = value;
return object;
} else {
object[array[0]] = objectifyHelper(array.slice(1), {});
return object;
}
}
function objectify(string) {
const tokens = string.split('.');
return objectifyHelper(tokens, {});
}
const str = 'user.first.name.robert';
const result = objectify(str);
console.log(result)
Note that this only changes your
object[array[0]] = objectifyHelper(array.slice(1), object);
to
object[array[0]] = objectifyHelper(array.slice(1), {});