1

I have a nested array of objects and want to get only the child property elements of an array. This is just an example and the actual data will include a unique children property in separate indices in the array. I am only able to traverse the first array in the list.

Here is my implementation:

const headers = [{
    id: "name1",
    title: "Name 1",
    children: [{
        title: "Children 1",
        child: [{
            title: "Child 1",
            onClick: "child1Click"
          },
          {
            title: "Child 2",
            onClick: "child2Click"
          }
        ]
      },
      {
        title: "CHildren 2",
        child: [{
            title: "Child 3",
            id: "child3Click"
          },
          {
            title: "Child 4",
            id: "child4Click"
          }
        ]
      }
    ]
  },
  {
    id: "name2",
    title: "Name 2",
    children: [{
        title: "Children 3",
        child: [{
            title: "Child 5",
            onClick: "child5Click"
          },
          {
            title: "Child 6",
            onClick: "child6Click"
          }
        ]
      },
      {
        title: "CHildren 4",
        child: [{
            title: "Child 7",
            id: "child7Click"
          },
          {
            title: "Child 8",
            id: "child8Click"
          }
        ]
      }
    ]
  },
  {
    id: "name3",
    title: "Name 3"
  },
  {
    id: "name4",
    title: "Name 4"
  }
]

console.log(_.flattenDeep(_.map(_.compact(_.map(headers, item => item.children))[0], item1 => item1.child)))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Expected Output:

[
  {
    "title": "Child 1",
    "onClick": "child1Click"
  },
  {
    "title": "Child 2",
    "onClick": "child2Click"
  },
  {
    "title": "Child 3",
    "id": "child3Click"
  },
  {
    "title": "Child 4",
    "id": "child4Click"
  },
  {
    "title": "Child 5",
    "onClick": "child5Click"
  },
  {
    "title": "Child 6",
    "onClick": "child6Click"
  },
  {
    "title": "Child 7",
    "id": "child7Click"
  },
  {
    "title": "Child 8",
    "id": "child8Click"
  }
]

Please advice.

Edit: I was able to get the required result using console.log(.flattenDeep(.map(.flattenDeep(.compact(_.map(headers, 'children'))), 'child')))

But is there an optimized version for doing the same? Thanks

1 Answer 1

3

Get the children with _.flatMap(), filter out the undefined values, and then use _.flatMap() again to get the values of the child property:

const headers = [{"id":"name1","title":"Name 1","children":[{"title":"Children 1","child":[{"title":"Child 1","onClick":"child1Click"},{"title":"Child 2","onClick":"child2Click"}]},{"title":"CHildren 2","child":[{"title":"Child 3","id":"child3Click"},{"title":"Child 4","id":"child4Click"}]}]},{"id":"name2","title":"Name 2","children":[{"title":"Children 3","child":[{"title":"Child 5","onClick":"child5Click"},{"title":"Child 6","onClick":"child6Click"}]},{"title":"CHildren 4","child":[{"title":"Child 7","id":"child7Click"},{"title":"Child 8","id":"child8Click"}]}]},{"id":"name3","title":"Name 3"},{"id":"name4","title":"Name 4"}]

const result = _.flatMap(_.compact(_.flatMap(headers, 'children')), 'child')

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

If you're using lodash/fp, you can generate a more readable function with _.flow():

const fn = _.flow(
  _.flatMap('children'),
  _.compact,
  _.flatMap('child')
)

const headers = [{"id":"name1","title":"Name 1","children":[{"title":"Children 1","child":[{"title":"Child 1","onClick":"child1Click"},{"title":"Child 2","onClick":"child2Click"}]},{"title":"CHildren 2","child":[{"title":"Child 3","id":"child3Click"},{"title":"Child 4","id":"child4Click"}]}]},{"id":"name2","title":"Name 2","children":[{"title":"Children 3","child":[{"title":"Child 5","onClick":"child5Click"},{"title":"Child 6","onClick":"child6Click"}]},{"title":"CHildren 4","child":[{"title":"Child 7","id":"child7Click"},{"title":"Child 8","id":"child8Click"}]}]},{"id":"name3","title":"Name 3"},{"id":"name4","title":"Name 4"}]

const result = fn(headers)

console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

Using lodash with _.flow() and _.partialRight():

const pr = _.partialRight;

const fn = _.flow(
  pr(_.flatMap, 'children'),
  _.compact,
  pr(_.flatMap, 'child')
)

const headers = [{"id":"name1","title":"Name 1","children":[{"title":"Children 1","child":[{"title":"Child 1","onClick":"child1Click"},{"title":"Child 2","onClick":"child2Click"}]},{"title":"CHildren 2","child":[{"title":"Child 3","id":"child3Click"},{"title":"Child 4","id":"child4Click"}]}]},{"id":"name2","title":"Name 2","children":[{"title":"Children 3","child":[{"title":"Child 5","onClick":"child5Click"},{"title":"Child 6","onClick":"child6Click"}]},{"title":"CHildren 4","child":[{"title":"Child 7","id":"child7Click"},{"title":"Child 8","id":"child8Click"}]}]},{"id":"name3","title":"Name 3"},{"id":"name4","title":"Name 4"}]

const result = fn(headers)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks buddy. I got a similar code to get the following done. I did using _.compact to get the truthy values. Is there any alternative way of doing this?
I actually prefer compact. Haven't used that one in eons. See my lodash/fp solution.
The second solution looks neat. I'll check it out. Thanks mate.
Note the use of lodash/fp. It can be done using lodash, but it requires partialRight.
Do you mind getting me a solution using partialRight?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.