Break down the problem into manageable pieces for better understanding of the process.
Start by converting each string into a usable format, like this:
"animal/mammal/dog"
which becomes:
[ "animal", "mammal", "dog" ]
This array represents the property names required to construct the final object.
You can achieve this with two functions: String.prototype.split()
to split the string into an array and Array.prototype.map()
to transform each element of the array:
let splitIntoNames = input.map(str => str.split('/'));
The resulting intermediate array looks like this:
[
[ "animal", "mammal", "dog" ],
[ "animal", "mammal", "cat", "tiger" ],
[ "animal", "mammal", "cat", "lion" ],
[ "animal", "mammal", "elephant" ],
[ "animal", "reptile" ],
[ "plant", "sunflower" ]
]
Next, iterate over each array using Array.prototype.forEach()
to add properties to the object. While you could use a for loop to add properties, let's do it recursively with a function called addName()
:
function addName(element, list, index) {
if (index >= list.length) {
return;
}
let name = list[index];
let isEndOfList = index === list.length - 1;
element[name] = element[name] || (isEndOfList ? true : {});
addName(element[name], list, index + 1);
}
let result = {};
splitIntoNames.forEach(list => {
addName(result, list, 0);
});
The final result is:
result: {
"animal": {
"mammal": {
"dog": true,
"cat": {
"tiger": true,
"lion": true
},
"elephant": true
},
"reptile": true
},
"plant": {
"sunflower": true
}
}
const input = [
"animal/mammal/dog",
"animal/mammal/cat/tiger",
"animal/mammal/cat/lion",
"animal/mammal/elephant",
"animal/reptile",
"plant/sunflower",
];
let splitIntoNames = input.map(str => str.split("/"));
console.log("splitIntoNames:", JSON.stringify(splitIntoNames, null, 2));
function addName(element, list, index) {
if (index >= list.length) {
return;
}
let name = list[index];
let isEndOfList = index === list.length - 1;
element[name] = element[name] || (isEndOfList ? true : {});
addName(element[name], list, index + 1);
}
let result = {};
splitIntoNames.forEach(list => {
addName(result, list, 0);
});
console.log("result:", JSON.stringify(result, null, 2));