How to get array of strings from nested object
Based on type it is required to get array of 'link'(s) Source object:
const obj = {
id: '01',
options: {},
children: [
{
id: '02',
type: 'green',
options: {
link: 'http://some-page-023'
},
children: [
{
id: '03',
type: 'black',
options: {},
children: [],
},
{
id: '04',
type: 'green',
options: {
link: 'http://some-page-044'
},
children: [
{
id: '05',
type: 'white',
options: {},
children: [],
}
],
}
],
},
{
id: '06',
type: 'black',
options: {
link: 'http://some-page-258'
},
children: [
{
id: '07',
type: 'green',
options: {
link: 'http://some-page-055'
},
children: [],
},
{
id: '08',
type: 'white',
options: {},
children: [
{
id: '09',
type: 'green',
options: {
link: 'http://some-page-023'
},
children: [],
}
],
}
],
},
]
}
What I am doing:
const a = []
const getLinks = (data, ltype) => {
if (data.children) {
for( let el in data.children) {
if (data.children[el].type === ltype) {
a.push(data.children[el].options.link)
}
getLinks(data.children[el], ltype)
}
}
return a
}
const result = getLinks(obj, 'green')
console.dir(result, { depth: null })
this works fine, result: [ 'http://some-page-023', 'http://some-page-044', 'http://some-page-055', 'http://some-page-023' ]
But I need the function to return the array of strings (array should be init and returned by function), so I need something like:
const getLinks = (data, ltype) => {
const a = []
function recursiveFind(children, ltype) {
if (data.children) {
for (let el in data.children) {
if (data.children[el].type === ltype) {
a.push(data.children[el].options.link)
} else {
recursiveFind(data.children[el], ltype)
}
}
}
}
recursiveFind(data, ltype)
return a
}
const result = getLinks(obj, 'green')
console.dir(result, { depth: null })
Your second snippet is actually fine, you just got the parameter wrong:
const getLinks = (data, ltype) => {
const a = []
function recursiveFind(data, ltype) {
if (data.children) {
for (let child of data.children) {
if (child.type === ltype)
a.push(child.options.link)
recursiveFind(child, ltype)
}
}
}
recursiveFind(data, ltype)
return a
}
Also note for..of
, it's better than for..in
.
Alternatively, you can get rid of the temp array and use a generator:
function *getLinks (data, ltype) {
if (data.children) {
for (let c of data.children) {
if (c.type === ltype)
yield c.options.link
yield *getLinks(c, ltype)
}
}
}
result = [...getLinks(obj, 'green')]