Reputation: 1510
I'm attempting to create an array of objects as the final output which includes the parent name and it's children. The id
would be the last child in the name
Sample output I'm trying to achieve :
[
{id:1,name:"1"},
{id:2,name:"1-2"},
{id:3,name:"1-2-3"},
{id:4,name:"1-2-4"}
]
Code:
let item = {
id: 1,
name: "1",
children: [{
id: 2,
name: "2",
children: [{
id: 3,
name: "3",
children: []
},
{
id: 4,
name: "4",
children: []
}
]
}]
}
const createList = (item) => {
let name = item.children.map(e => {
return createList(e)
})
return item.name + "-" + name
}
console.log(createList(item))
Upvotes: 2
Views: 76
Reputation: 50797
I think we can do this more simply. I'd prefer code like this:
const convert = ({id, name, children}, prefix = '') => [
{id, name: prefix + name},
...children .flatMap (c => convert (c, prefix + name + '-'))
]
const sample = {id: 1, name: "1", children: [{id: 2, name: "2", children: [{id: 3, name: "3", children: []}, {id: 4, name: "4", children: []}]}]}
console .log (convert (sample))
.as-console-wrapper {max-height: 100% !important; top: 0}
Note that our recursion bottoms without an explicit case for it because mapping over an empty array returns an empty array, without making further calls. And that result is just folded into our accumulation by flatMap
.
If you prefer not to include default parameters (and there are some good reasons for that preference), you could simply wrap an internal version of this function into a public function, supplying the initial prefix
value to that internal one. This would also allow us to simplify the function reference passed to flatMap
:
const _convert = (prefix = '') => ({id, name, children}) => [
{id, name: prefix + name},
...children .flatMap (_convert (prefix + name + '-'))
]
const convert = _convert ('')
const sample = {id: 1, name: "1", children: [{id: 2, name: "2", children: [{id: 3, name: "3", children: []}, {id: 4, name: "4", children: []}]}]}
console .log (convert (sample))
.as-console-wrapper {max-height: 100% !important; top: 0}
Upvotes: 0
Reputation: 10826
A simple recursion will do the trick:
let item = {
id: 1,
name: "1",
children: [{
id: 2,
name: "2",
children: [{
id: 3,
name: "3",
children: []
},
{
id: 4,
name: "4",
children: []
}
]
}]
}
var result = []
const createList = (items, acc) => {
items.forEach(item => {
const newAcc = {
id: item.id,
name: acc ? `${acc.name}-${item.name}` : `${item.name}`
}
result.push(newAcc)
createList(item.children, newAcc)
})
}
createList([item], null)
console.log(result)
Upvotes: 3
Reputation: 21
You're on the right track with recursion, but the map function is probably not the best choice for this. Map function doesn't work the way you might expect when there is only one element in the array, as it is not meant to be used to process lists in such a way, but only to "map" data.
Try switching to a for loop or foreach and building the string yourself.
Example:
let sample = {
id: 1,
name: "1",
children: [{
id: 2,
name: "2",
children: [{
id: 3,
name: "3",
children: []
},
{
id: 4,
name: "4",
children: []
}
]
}]
};
function buildArray(input, parentName) {
let output = [];
for (let item of input) {
let name = parentName ? `${parentName}-${item.name}` : item.name;
output.push({ id: item.id, name: name });
if (item.children) {
output = output.concat(buildArray(item.children, name));
}
}
return output;
}
let result = buildArray(sample.children, sample.name);
let output = document.getElementById('myresult');
output.innerText = JSON.stringify(result);
<p id="myresult"></p>
Upvotes: 2