Home > Software engineering >  Counting all nested objects in array where selected attribute is true
Counting all nested objects in array where selected attribute is true

Time:02-02

I need to create a recursive function counting objects nested in the array where the selected attribute is true.

var data = [
  {
"id": 1,
"code": "1",
"selected": false,
"children": [
  {
    "id": 4,
    "code": "1.01",
    "selected": false,
    "children": [
      {
        "id": 5,
        "code": "1.01.001",
        "selected": true,
        "children": []
      },
      {
        "id": 6,
        "code": "1.01.002",
        "selected": false,
        "children": []
      },
      {
        "id": 20,
        "code": "1.01.003",
        "selected": true,
        "children": []
      }
    ]
  }
]
  },
  {
"id": 2,
"code": "2",
"selected": false,
"children": [
  {
    "id": 7,
    "code": "2.01",
    "selected": false,
    "children": [
      {
        "id": 9,
        "code": "2.01.001",
        "selected": true,
        "children": []
      },
      {
        "id": 21,
        "code": "2.01.002",
        "selected": true,
        "children": []
      },
      {
        "id": 22,
        "code": "2.01.003",
        "selected": false,
        "children": []
      }
    ]
  }
]
  },
  {
"id": 3,
"code": "3",
"selected": false,
"children": [
  {
    "id": 8,
    "code": "3.01",
    "selected": false,
    "children": [
      {
        "id": 10,
        "code": "3.01.01",
        "name": "Sementes",
        "selected": false,
        "children": [
          {
            "id": 11,
            "code": "3.01.01.001",
            "selected": true,
            "children": []
          },
          {
            "id": 23,
            "code": "3.01.01.002",
            "selected": false,
            "children": []
          },
          {
            "id": 24,
            "code": "3.01.01.003",
            "selected": true,
            "children": []
          }
        ]
      },
      {
        "id": 25,
        "code": "3.01.02",
        "selected": false,
        "children": [
          {
            "id": 27,
            "code": "3.01.02.001",
            "selected": true,
            "children": []
          },
          {
            "id": 28,
            "code": "3.01.02.002",
            "selected": false,
            "children": []
          },
          {
            "id": 29,
            "code": "3.01.02.003",
            "selected": false,
            "children": []
          }
        ]
      },
      {
        "id": 26,
        "code": "3.01.03",
        "selected": false,
        "children": [
          {
            "id": 30,
            "code": "3.01.03.001",
            "selected": true,
            "children": []
          },
          {
            "id": 31,
            "code": "3.01.03.002",
            "selected": true,
            "children": []
          },
          {
            "id": 32,
            "code": "3.01.03.003",
            "selected": true,
            "children": []
          },
          {
            "id": 35,
            "code": "3.01.03.004",
            "selected": false,
            "children": []
          },
          {
            "id": 34,
            "code": "3.01.03.005",
            "selected": false,
            "children": []
          }
        ]
      }
    ]
  }
]
  }
];


const countSelectedChildren = (arr) => {

return arr;
}

console.log(countSelectedChildren(data))

Expected response:

{
    "id": 3,
    "code": "3",
    "selected": false,
    "selectedChildren": 6,
    "children": [
      {
        "id": 8,
        "code": "3.01",
        "selected": false,
        "selectedChildren": 6,
        "children": [
          {
            "id": 10,
            "code": "3.01.01",
            "name": "Sementes",
            "selected": false,
            "selectedChildren": 2,
            "children": [
              {
                "id": 11,
                "code": "3.01.01.001",
                "selected": true,
                "children": []
              },
              {
                "id": 23,
                "code": "3.01.01.002",
                "selected": false,
                "children": []
              },
              {
                "id": 24,
                "code": "3.01.01.003",
                "selected": true,
                "children": []
              }
            ]
          },
          {
            "id": 25,
            "code": "3.01.02",
            "selected": false,
            "selectedChildren": 1,
            "children": [
              {
                "id": 27,
                "code": "3.01.02.001",
                "selected": true,
                "children": []
              },
              {
                "id": 28,
                "code": "3.01.02.002",
                "selected": false,
                "children": []
              },
              {
                "id": 29,
                "code": "3.01.02.003",
                "selected": false,
                "children": []
              }
            ]
          },
          {
            "id": 26,
            "code": "3.01.03",
            "selected": false,
            "selectedChildren": 3,
            "children": [
              {
                "id": 30,
                "code": "3.01.03.001",
                "selected": true,
                "children": []
              },
              {
                "id": 31,
                "code": "3.01.03.002",
                "selected": true,
                "children": []
              },
              {
                "id": 32,
                "code": "3.01.03.003",
                "selected": true,
                "children": []
              },
              {
                "id": 35,
                "code": "3.01.03.004",
                "selected": false,
                "children": []
              },
              {
                "id": 34,
                "code": "3.01.03.005",
                "selected": false,
                "children": []
              }
            ]
          }
        ]
      }
    ]
  }

Can you help me to create this recursive function?

const countSelectedChildren = (arr) => {

return arr;
}

Thanks for your help!

CodePudding user response:

You could take a recursive function for an array and return an object with a counting property and a children array.

const
    addSelected = array => {
        let selectedChildren = 0;
        const
            children = array.map(({ children, ...o }) => {
                if (o.selected) selectedChildren  ;
                const temp = addSelected(children);
                selectedChildren  = temp.selectedChildren || 0;
                return { ...o, ...temp };
            });

        return children.length
            ? { selectedChildren, children }
            : { children };
    },
    data = [{ id: 1, code: "1", selected: false, children: [{ id: 4, code: "1.01", selected: false, children: [{ id: 5, code: "1.01.001", selected: true, children: [] }, { id: 6, code: "1.01.002", selected: false, children: [] }, { id: 20, code: "1.01.003", selected: true, children: [] }] }] }, { id: 2, code: "2", selected: false, children: [{ id: 7, code: "2.01", selected: false, children: [{ id: 9, code: "2.01.001", selected: true, children: [] }, { id: 21, code: "2.01.002", selected: true, children: [] }, { id: 22, code: "2.01.003", selected: false, children: [] }] }] }, { id: 3, code: "3", selected: false, children: [{ id: 8, code: "3.01", selected: false, children: [{ id: 10, code: "3.01.01", name: "Sementes", selected: false, children: [{ id: 11, code: "3.01.01.001", selected: true, children: [] }, { id: 23, code: "3.01.01.002", selected: false, children: [] }, { id: 24, code: "3.01.01.003", selected: true, children: [] }] }, { id: 25, code: "3.01.02", selected: false, children: [{ id: 27, code: "3.01.02.001", selected: true, children: [] }, { id: 28, code: "3.01.02.002", selected: false, children: [] }, { id: 29, code: "3.01.02.003", selected: false, children: [] }] }, { id: 26, code: "3.01.03", selected: false, children: [{ id: 30, code: "3.01.03.001", selected: true, children: [] }, { id: 31, code: "3.01.03.002", selected: true, children: [] }, { id: 32, code: "3.01.03.003", selected: true, children: [] }, { id: 35, code: "3.01.03.004", selected: false, children: [] }, { id: 34, code: "3.01.03.005", selected: false, children: [] }] }] }] }],
    result = addSelected(data).children;

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

CodePudding user response:

const countSelectedChildren = (data) => {
   let length = 0;
   for (item of data) {
      item.selected && (length  )
      length  = countSelectedChildren(item.children || [])
   }
   return length;
}

CodePudding user response:

I would approach it like this

    const countSelectedChildren = (inArr) => {
        
        const outArr = [];
        
        inArr.forEach(row => {
        
          //  simply count all chilren with selected=true
          row.SelectedChildren = row.children.filter(row => row.selected).length;
        
          //  if there are children, call this function on them
          if (row.children.length) {
             row.children = countSelectedChildren(row.children);
          }
          
          outArr.push(row);
        });
        
        return outArr;
        
    }

const data = [
  {
"id": 1,
"code": "1",
"selected": false,
"children": [
  {
    "id": 4,
    "code": "1.01",
    "selected": false,
    "children": [
      {
        "id": 5,
        "code": "1.01.001",
        "selected": true,
        "children": []
      },
      {
        "id": 6,
        "code": "1.01.002",
        "selected": false,
        "children": []
      },
      {
        "id": 20,
        "code": "1.01.003",
        "selected": true,
        "children": []
      }
    ]
  }
]
  },
  {
"id": 2,
"code": "2",
"selected": false,
"children": [
  {
    "id": 7,
    "code": "2.01",
    "selected": false,
    "children": [
      {
        "id": 9,
        "code": "2.01.001",
        "selected": true,
        "children": []
      },
      {
        "id": 21,
        "code": "2.01.002",
        "selected": true,
        "children": []
      },
      {
        "id": 22,
        "code": "2.01.003",
        "selected": false,
        "children": []
      }
    ]
  }
]
  },
  {
"id": 3,
"code": "3",
"selected": false,
"children": [
  {
    "id": 8,
    "code": "3.01",
    "selected": false,
    "children": [
      {
        "id": 10,
        "code": "3.01.01",
        "name": "Sementes",
        "selected": false,
        "children": [
          {
            "id": 11,
            "code": "3.01.01.001",
            "selected": true,
            "children": []
          },
          {
            "id": 23,
            "code": "3.01.01.002",
            "selected": false,
            "children": []
          },
          {
            "id": 24,
            "code": "3.01.01.003",
            "selected": true,
            "children": []
          }
        ]
      },
      {
        "id": 25,
        "code": "3.01.02",
        "selected": false,
        "children": [
          {
            "id": 27,
            "code": "3.01.02.001",
            "selected": true,
            "children": []
          },
          {
            "id": 28,
            "code": "3.01.02.002",
            "selected": false,
            "children": []
          },
          {
            "id": 29,
            "code": "3.01.02.003",
            "selected": false,
            "children": []
          }
        ]
      },
      {
        "id": 26,
        "code": "3.01.03",
        "selected": false,
        "children": [
          {
            "id": 30,
            "code": "3.01.03.001",
            "selected": true,
            "children": []
          },
          {
            "id": 31,
            "code": "3.01.03.002",
            "selected": true,
            "children": []
          },
          {
            "id": 32,
            "code": "3.01.03.003",
            "selected": true,
            "children": []
          },
          {
            "id": 35,
            "code": "3.01.03.004",
            "selected": false,
            "children": []
          },
          {
            "id": 34,
            "code": "3.01.03.005",
            "selected": false,
            "children": []
          }
        ]
      }
    ]
  }
]
  }
];


const countSelectedChildren = (inArr) => {
    
    const outArr = [];
    
    inArr.forEach(row => {
    
      //  simply count all chilren with selected=true
      row.SelectedChildren = row.children.filter(row => row.selected).length;
    
      //  if there are children, call this function on them
      if (row.children.length) {
         row.children = countSelectedChildren(row.children);
      }
      
      outArr.push(row);
    });
    
    return outArr;
    
}

console.log(countSelectedChildren(data))

  • Related