rolfo85
rolfo85

Reputation: 767

Recursive function with an Object in JS

I have an array that contains objects that might have nth levels of depth.

Something like this:

const settings = [

    {path: '/templates/pictures.php', url: '/pictures', label: 'Pictures', component: 'tab', template: 'default'},
    {path: '/templates/post-article.php', url: '/user/:username', component: 'table', template: 'default', children:[
        {path: '/templates/post-article-highlights.php', url: '/user/:username/highlights', component: 'table', template: 'default', children:[
              {path: '/templates/post-article-highlights.php', url: '/user/:username/highlights', component: 'table', template: 'default'}  

        ]}  
    ]}

]

I need to push on a different array only the 'Url' property and the children property if present, preserving the depth though.

So the new array should look like this:

const newArray = [

    {url: '/pictures'},
    {url: '/user/:username', children:[
        {url: '/user/:username/highlights', children:[
                {url: '/user/:username/highlights'} 
        ]}  
    ]}

]

Can you help me?

Thanks

Upvotes: 3

Views: 3887

Answers (3)

EugenSunic
EugenSunic

Reputation: 13723

Here is an easy and understandable approach along with a a fiddle example where you can test it further:

https://jsfiddle.net/eugensunic/pftkosb9/

function findArray(array) {
  var new_array = [];

  for (var i = 0; i < array.length; i++) {
    if (array[i].url) {
      let obj = {};
      obj['url'] = array[i].url;
      obj['children'] = array[i].children;

      new_array.push(obj);

    }
    if (Array.isArray(array[i].children)) {
      new_array = new_array.concat(findArray(array[i].children));
    }
  }
  return new_array;
}

console.log(findArray(settings));

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386858

You could use a destructuring assignment for the wanted keys and use Array#map for getting a new array with only the one property and use Object.assign for the children objects by checking the children and if exist, take the urls from the children with a recursive call of the function.

function getUrls(array) {
    return array.map(({ url, children }) =>
        Object.assign({ url }, children && { children: getUrls(children) }));
}

var settings = [{ path: '/templates/pictures.php', url: '/pictures', label: 'Pictures', component: 'tab', template: 'default' }, { path: '/templates/post-article.php', url: '/user/:username', component: 'table', template: 'default', children: [{ path: '/templates/post-article-highlights.php', url: '/user/:username/highlights', component: 'table', template: 'default', children: [{ path: '/templates/post-article-highlights.php', url: '/user/:username/highlights', component: 'table', template: 'default' }] }] }],
    urls = getUrls(settings);

console.log(urls);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 2

const settings = [
    {path: '/templates/pictures.php', url: '/pictures', label: 'Pictures', component: 'tab', template: 'default'},
    {path: '/templates/post-article.php', url: '/user/:username', component: 'table', template: 'default', children:[
        {path: '/templates/post-article-highlights.php', url: '/user/:username/highlights', component: 'table', template: 'default', children:[
              {path: '/templates/post-article-highlights.php', url: '/user/:username/highlights', component: 'table', template: 'default'}  

        ]}  
    ]}
];


function childrenUrls(childrens){
	return childrens.reduce(function(arr, obj){
		var newObj = {url: obj.url};
		if(obj.children) newObj.children = childrenUrls(obj.children);
		return arr.push(newObj), arr;
	}, []);
}


const newArray = childrenUrls(settings);

console.log(newArray);

Upvotes: 1

Related Questions