0

I want to filter a nested array by element field value. Here is the array need to filter. I want to filter by element checked value, If value equal true, return, false, discard the element.

let rawData =[
      {
        name: 'red',
        checked: true,
        children: [
          {
            name: 'red1',
            checked: false,
            children: [
              {
                name: 'red11',
                checked: true,
                children: [
                  {
                    name: 'red111',
                    checked: false,
                    children: [
                      {
                        name: 'red1111',
                        checked: true,
                        children: []
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        name: 'blue',
        checked: false,
        children: [
          {
            name: 'blue1',
            checked: true,
            children: [
              {
                name: 'blue11',
                checked: true,
                children: []
              },
               {
                name: 'blue12',
                checked: false,
                children: []
              },
            ]
          }
        ]
      },
      {
       name: 'yellow',
       checked: false,
       children: []
      }
    ]

Here is the result i want. (Filter every element and return it with checked equal true. If not equal true, just discard.

 let result =[
      {
        name: 'red',
        checked: true,
        children: [
          {
            name: 'red11',
            checked: true,
            children: [
              {
                name: 'red1111',
                checked: true,
                children: []
              }
            ]
          }
        ]   
      },
        {
          name: 'blue1',
          checked: true,
          children: [
            {
              name: 'blue11',
              checked: true,
              children: []
            }
          ]
        }
      ]

Here is my solution. (won't work)

let result = rawData.filter(node => {
  function getCheckedData (node) {
    if (node.checked === true) {
      return node
    }
    if (node.children.length) {
      node.children.filter(c => {
        getCheckedData(c)
      })
    }
   return getCheckedData(node)
})

node.children.filter never execute if first level data checked equal true. What should i do to make make children recursive go on no matter parent checked status. Thanks~~

2
  • Are you actually trying to support the checked value of the string "false"? What do you expect that to equate to? True? False? Commented May 24, 2020 at 4:13
  • There is something odd about your requirements. You're returning a tree, but the output structure is only slightly related to the input one. In the input, red1111 is a grandchild of red11. But in the output it's a child. Are you sure you don't want a flat list for the output? Commented May 24, 2020 at 20:18

1 Answer 1

3

This does not account for your use of checked: 'false', which is a truthy value but is the word false... so ¯\_(ツ)_/¯ I'll assume literal false.

let rawData =[
      {
        name: 'red',
        checked: true,
        children: [
          {
            name: 'red1',
            //checked: 'false', // ¯\_(ツ)_/¯
            checked: false,
            children: [
              {
                name: 'red11',
                checked: true,
                children: [
                  {
                    name: 'red111',
                    checked: false,
                    children: [
                      {
                        name: 'red1111',
                        checked: true,
                        children: []
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        name: 'blue',
        checked: false,
        children: [
          {
            name: 'blue1',
            checked: true,
            children: [
              {
                name: 'blue11',
                checked: true,
                children: []
              },
               {
                name: 'blue12',
                checked: false,
                children: []
              },
            ]
          }
        ]
      },
      {
       name: 'yellow',
       checked: false,
       children: []
      }
    ];

function checkedStuff(arr) {
  return arr.flatMap(
    a => a.checked
    ? {...a, children: checkedStuff(a.children)}
    : checkedStuff(a.children)
  );
}

console.log(checkedStuff(rawData));

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

1 Comment

a beautiful use of flatMap and recursion

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.