Search code examples
javascriptunderscore.jslodashflattenflatmap

deep flatten all items in collection using lodash


I'm looking to flatten an array that look like this:

[{
    "id": 0,
    "text": "item 0"
}, {
    "id": 1,
    "items": [{
        "id": 2,
        "text": "item 2"
    }, {
        "id": 3,
        "items": [{
            "id": 4,
            "text": "item 4"
        }]
    }]
}]

into this

[{
    "id": 0,
    "text": "item 0"
}, {
    "id": 2,
    "text": "item 2"
}, {
    "id": 4,
    "text": "item 4"
}]

basically keeping all element that doesn't have an "items" property, and if they have one, recursively traverse all "items" arrays deep.

I could indeed write a recursive function, but I'm looking for a nice looking lodash or underscore way to solve this.


Solution

  • There is no neat function for this in lodash or underscore. I think a recursive function is your best bet:

    function collect(array, result) {
      array.forEach(function(el) {
        if(el.items) {
          collect(el.items, result);
        } else {
          result.push(el);
        }
      });
    }
    

    var array = [{
        "id": 0,
        "text": "item 0"
    }, {
        "id": 1,
        "items": [{
            "id": 2,
            "text": "item 2"
        }, {
            "id": 3,
            "items": [{
                "id": 4,
                "text": "item 4"
            }]
        }]
    }];
    
    function collect(array, result) {
      array.forEach(function(el) {
        if(el.items) {
          collect(el.items, result);
        } else {
          result.push(el);
        }
      });
    }
    var result = [];
    collect(array, result);
    console.log(result);