skip to Main Content
const array= [
  {
    "groupId": "group1",
    "devices": ["5","6"],
    "children": [
      {
        "groupId": "group11",
        "devices": ["1","2","3","4"],
        "children": [
          {
            "groupId": "group111",
            "devices": ["7","8","9","0"],
            "children": []
          },
          {
            "groupId": "group112",
            "devices": ["7","8","9","0"],
            "children": []
          }
        ]
      },
      {
        "groupId": "group12",
        "devices": ["1","2","3","4"],
        "children": [
          {
            "groupId": "group121",
            "devices": ["7","8","9","0"],
            "children": []
          }
        ]
      }
    ]
  }
]

This is an array which could have n number of children nested.
The expected outcome with a recursive typescript function should return the count of all devices under a group.

For example:

group1 : 22
group11 : 12
group11 : 8
group121 : 4

I have created a method which would generate the count and add to the array which is not generating the desired results.

this.getdevicesCount(this.array, 0);


/**
     * Recursive method to find Number of devices in a group
     */
    getdevicesCount(array: any[], devcount: number) {
        array.forEach((group) => {
            devcount = devcount + group.devices.length;
            if(group.children.length) {
                this.getdevicesCount(group.children, devcount);
            }
            group.count = devcount;
            devcount = 0;
        });
    }

2

Answers


  1. The issue is that in JS/TS, arguments are passed by value. In particular, your 2nd parameter devcount is a primitive type (number), so there is no way modifying its value within the body of this.getdevicesCount function could have the side effect of modifying the argument value outside.

    Instead of trying to modify the argument value, you could just return it:

    getdevicesCount(array: any[]) {
      const total = 0;
      array.forEach((group) => {
        group.count =
          group.devices.length
          + this.getdevicesCount(group.children);
        total += group.count;
      });
      return total;
    }
    
    Login or Signup to reply.
  2. Your function only computes a value for a single key, if you want all counts in an object, you’ll need a function that returns the count and populates the object at the same time, for example:

    function count(arr) {
        let res = {}
    
        function cnt(a) {
            res[a.groupId] = a.devices?.length ?? 0
            for (let c of (a.children ?? []))
                res[a.groupId] += cnt(c)
            return res[a.groupId]
        }
    
        for (let a of arr)
            cnt(a)
    
        return res
    
    }
    
    //
    
    const array= [
        {
            "groupId": "group1",
            "devices": ["5","6"],
            "children": [
                {
                    "groupId": "group11",
                    "devices": ["1","2","3","4"],
                    "children": [
                        {
                            "groupId": "group111",
                            "devices": ["7","8","9","0"],
                            "children": []
                        },
                        {
                            "groupId": "group112",
                            "devices": ["7","8","9","0"],
                            "children": []
                        }
                    ]
                },
                {
                    "groupId": "group12",
                    "devices": ["1","2","3","4"],
                    "children": [
                        {
                            "groupId": "group121",
                            "devices": ["7","8","9","0"],
                            "children": []
                        }
                    ]
                }
            ]
        }
    ]
    
    //
    
    console.log(count(array))
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search