Search code examples
javascriptarraysfilteringlodash

Lodash iterate function for nested array object


Need better solution to extract data from nested objects. I'm currently working with an object that is a nested array.

let data = [
    {
        name: "Var 1",
        id: "1",
        child: [
            {
                name: "Var 2",
                id: "2",
                child: [
                    {
                        name: "Var 3",
                        id: "3",
                    },
                    {
                        name: "Var 4",
                        id: "4",
                    },
                ],
            },
{
                name: "Var 5",
                id: "5",
                child: [
                    {
                        name: "Var 6",
                        id: "6",
                    },
                    {
                        name: "Var 7",
                        id: "7",
                    },
                ],
            },
        ],
    },
];

what i have for searching this data is just id from last child, e.g:

let knownId = 3

and i`m expect the outcome is just like this

[
    {
        name: "Var 1",
        id: "1",
        child: [
            { name: "Var 2", id: "2", child: [{ name: "Var 3", id: "3" }] },
        ],
    },
];

im using lodash for simple silly solution like this

let first: any = _.filter(data, (i1: any) =>
    _.some(i1.child, (i2) => _.some(i2.child, (i3) => i3.id == knownId ))
);

let secondData: any = _.cloneDeep(_.first(first));

let second: any = _.filter(secondData.child, (i1: any) =>
    _.some(i1.child, (i2) => i2.id == knownId )
);

I got the expected result after some map and join, but I know it's not optimal. So I'm going to try another solution that uses a function like this.

function deep(arr: any, id: any) {
  _.some(arr, function (val) {
    if (val.id == id) return true;
    if (_.isArray(val.child)) {
      deep(val.child, id);
    }
  });
}

But when I call this function from within the filter method, it simply does not work and returns undefined. I require a better solution to my problem in order to improve my data filtering performance. Please kindly help me. thanks :)


Solution

  • I guess your filter could be like this

    function hasDeep(arr, id) {
      return arr.some(function (val) {
        if (val.id == id) return true;
        if (Array.isArray(val.child) && hasDeep(val.child, id)) return true;
      });
    }