I'm trying to convert array of strings with dots between names. I want to make an array of object like in const out. I tried to make it by reduceRight, but I don't know how to combine fields.
My code:
const input = ['apples', 'bananas.kivi.grape', 'bananas.orange', 'bananas.strawberry'];
const res = input.map((item) => {
const splInp = item.split('.');
return splInp.reduceRight((acc, item) => {
if (Object.keys(acc).length !== 0) {
return {
children: [acc],
"name": item
};
} else {
return {
"name": item
};
}
}, []/* as any*/);
});
console.log(res);
Desired output:
const out = [
{ name: 'apples' },
{
name: 'bananas',
children: [
{
name: 'kivi',
children: [
{
name: 'grape',
},
],
},
{ name: 'orange' },
{ name: 'strawberry' },
],
},
];
You can solve it using a trie
Whenever you get a string, just traverse your tree and eventually add any leaf (if you can't traverse more)
const input = ['apples', 'bananas.kivi.grape', 'bananas.orange', 'bananas.strawberry', 'apples.are.good', 'apples.are.not.good'];
const Trie = () => {
const root = {}
const add = s => {
s.split('.').reduce((acc, tok) => {
if (!acc[tok]) {
// add the leaf
acc[tok] = { children: {} }
}
// traverse the node
return acc[tok].children
}, root)
}
const toJSON = (node = root) => {
return Object.entries(node).map(([name, { children }]) => ({
name, children: toJSON(children)
}))
}
return { add, toJSON }
}
const t = Trie()
input.forEach(t.add)
console.log(JSON.stringify(t.toJSON(), null, 2))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With