skip to Main Content

I have a 3-layer array that I want to filter out data based on the child array values. I can get semi-correct results but the last part I am having issues with.

{
    "id": 1,
    "grandparent": "Timmy",
    "parents": [
        {
            "id": 1,
            "parent": "Johnny",
            "children": [
                {
                    "id": 1,
                    "child": "Sam",
                    "checked": true
                },
                {
                    "id": 1,
                    "child": "Ted",
                    "checked": false
                }
            ]
        },
        {
            "id": 2,
            "parent": "Jessica",
            "children": [
                {
                    "id": 1,
                    "child": "Sam",
                    "checked": false
                }
            ]
        },
    ]
}

I have this so far:

    grandparents.value = value.value.map((el) => ({
        ...el,
        parents: el.components.filter((parent) => parent.children?.some((child) => child.checked))
    }))

and it returns this result:

{
    "id": 1,
    "grandparent": "Timmy",
    "parents": [
        {
            "id": 1,
            "parent": "Johnny",
            "children": [
                {
                    "id": 1,
                    "child": "Sam",
                    "checked": true
                },
                {
                    "id": 1,
                    "child": "Ted",
                    "checked": false
                }
            ]
        }
    ]
}

So the parents array is working. However, I also need the children array to also filter out if they are not checked.

Expected results

{
    "id": 1,
    "grandparent": "Timmy",
    "parents": [
        {
            "id": 1,
            "parent": "Johnny",
            "children": [
                {
                    "id": 1,
                    "child": "Sam",
                    "checked": true
                }
            ]
        }
    ]

2

Answers


  1. filter() will only add or remove the object, not alter the inner children array.


    You could adopt a reduce() option where you

    1. for each parent, filter the children
    2. if we got a child, add this object with the updated children array
    3. otherwise, don’t add this parent
    let data = {"id": 1, "grandparent": "Timmy", "parents": [{"id": 1, "parent": "Johnny", "children": [{"id": 1, "child": "Sam", "checked": true }, {"id": 1, "child": "Ted", "checked": false } ] }, {"id": 2, "parent": "Jessica", "children": [{"id": 1, "child": "Sam", "checked": false } ] } ] };
    
    data.parents = data.parents.reduce((p, c) => {
      const children = c.children.filter(c => c.checked);
      if (children.length) {
          return [ ...p, { ...c, children } ];
      }
      return p;
    }, []);
    
    console.log(data);

    {
      "id": 1,
      "grandparent": "Timmy",
      "parents": [
        {
          "id": 1,
          "parent": "Johnny",
          "children": [
            {
              "id": 1,
              "child": "Sam",
              "checked": true
            }
          ]
        }
      ]
    }
    
    Login or Signup to reply.
  2. map over the parents array, for each parent, we filter the children array to keep only the checked ones, after that use filter() again to remove parents whose children array is empty after filtering.

    const data = {
        "id": 1,
        "grandparent": "Timmy",
        "parents": [
            {
                "id": 1,
                "parent": "Johnny",
                "children": [
                    {
                        "id": 1,
                        "child": "Sam",
                        "checked": true
                    },
                    {
                        "id": 1,
                        "child": "Ted",
                        "checked": false
                    }
                ]
            },
            {
                "id": 2,
                "parent": "Jessica",
                "children": [
                    {
                        "id": 1,
                        "child": "Sam",
                        "checked": false
                    }
                ]
            },
        ]
    }
    
    const filteredData = {
      id: data.id,
      grandparent: data.grandparent,
      parents: data.parents.map((parent) => ({
        id: parent.id,
        parent: parent.parent,
        children: parent.children.filter((child) => child.checked)
      })).filter((parent) => parent.children.length > 0)
    };
    
    console.log(filteredData)
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search