Recursively iterate through arrays with Lodash

3.8k Views Asked by At

I want to use underscore to go iterate each item and append a period to the end of each fruit's name, and return an array. But there can be many nested levels.

`const` `NESTED =` `[
       {name: 'Apple', 
        items: [{
                 name: 'Orange', 
                 items: [{name: 'Banana'}]
              }]}, 
       {name: 'Pear'}]`

My final should look like this:

`NESTED =` `[{ name: 'Apple.', items: [{name: 'Orange.', items: [{name: 'Banana.'}]}]}, { name: 'Pear.'}]`

There can be many and many items within. This is where I am stuck, my current underscore function only gets the first level, using ._map:

let items = _.map(NESTED, function(item){
            return {
                // append the period here, but doesn't go deeper
            }
        });

What is a good way to do this?

3

There are 3 best solutions below

0
On BEST ANSWER

This should work for the example data that you supplied.

var pre = document.getElementById('out'),
    NESTED = [{
        name: 'Apple',
        items: [{
            name: 'Orange',
            items: [{
                name: 'Banana'
            }]
        }]
    }, {
        name: 'Pear'
    }];

function recurse(arr) {
    var res = arr.map(function (item) {
        return Object.keys(item).reduce(function (acc, key) {
            if (key === 'name') {
                acc[key] = item[key] + '.';
            } else if (key === 'items') {
                acc[key] = recurse(item[key]);
            }

            return acc;
        }, {});
    });

    return res;
}

pre.textContent = 'New\n\n';
pre.textContent += JSON.stringify(recurse(NESTED), null, 2) + '\n\n';
pre.textContent += 'Original\n\n';
pre.textContent += JSON.stringify(NESTED, null, 2);
<pre id="out"></pre>

Should be easy enough to translate the pure JS into underscore.

Update: direct conversion to underscore

var pre = document.getElementById('out'),
    NESTED = [{
        name: 'Apple',
        items: [{
            name: 'Orange',
            items: [{
                name: 'Banana'
            }]
        }]
    }, {
        name: 'Pear'
    }];

function recurse(arr) {
    var res = _.map(arr, function (item) {
        return _.reduce(_.keys(item), function (acc, key) {
            if (key === 'name') {
                acc[key] = item[key] + '.';
            } else if (key === 'items') {
                acc[key] = recurse(item[key]);
            }

            return acc;
        }, {});
    });

    return res;
}

pre.textContent = 'New\n\n';
pre.textContent += JSON.stringify(recurse(NESTED), null, 2) + '\n\n';
pre.textContent += 'Original\n\n';
pre.textContent += JSON.stringify(NESTED, null, 2);
<script src="http://underscorejs.org/underscore-min.js"></script>
<pre id="out"></pre>

0
On

The answer is already here looping through arrays of arrays

var printArray = function(arr) {
  if ( typeof(arr) == "object") {
    for (var i = 0; i < arr.length; i++) {
        printArray(arr[i]);
    }
  }
else document.write(arr);
}

printArray(parentArray);
0
On

just a quick attempt

var findMyChildren = function(this, parent){
    if(parent !== null){
        this[name] = child[name] + '.';
    }

    if(child[items] !== null){
        for(var i=0;i<child[items].length;i++){
            var child = this[items][i];
            findMyChildren(child, this);
        }
    }   
};