0

I have a below object where I am trying to group data using department and sub department value. I have tried using reduce function on the department name but could not achieve the desired result.

For example, I have an array of department objects:

var arr = //Actual Object
  [{
      "department": "Admin",
      "sub_department": [{
        "name": "Finance",
        "application": [{
          "name": "F1",
          "tag": 100
        }]
      }]
    },
    {
      "department": "Admin",
      "sub_department": [{
        "name": "Registry",
        "application": [{
          "name": "R2",
          "tag": 200
        }]
      }]
    },
    {
      "department": "Admin",
      "sub_department": [{
        "name": "Finance",
        "application": [{
          "name": "F2",
          "tag": 200
        }]
      }]
    },
    {
      "department": "Helpdesk",
      "sub_department": [{
        "name": "Entry",
        "application": [{
          "name": "E1",
          "tag": 200
        }]
      }]
    }
  ]

//Tried below code
var result = arr.reduce(function(r, a) {
  r[a.department] = r[a.department] || [];
  r[a.department].push(a);
  return r;
}, Object.create(null));

console.log(result)

And I am trying to achieve the desired result by grouping same department and if both department and sub_department.name is same then pushing the application into sub_department array.

[
  {
    "department": "Admin",
    "sub_department": [
      {
        "name": "Finance",
        "application": [
          {
            "name": "F1",
            "tag": 100
          },
          {
            "name": "F2",
            "tag": 200
          }
        ]
      },
      {
        "name": "Registry",
        "application": [
          {
            "name": "R2",
            "tag": 200
          }
        ]
      }
    ]
  },
  {
    "department": "Helpdesk",
    "sub_department": [
      {
        "name": "Entry",
        "application": [
          {
            "name": "E1",
            "price": 200
          }
        ]
      }
    ]
  }
]

Any help on this will be really helpful.

1

2 Answers 2

1

You were actually quite close. Just build up objects as the hashtables values and use Object.values to turn the hashtable into an array:

var result = Object.values(arr.reduce(function(r, a) { //<--- the hashtable > array conversion
  r[a.department] = r[a.department] || {
     department: a.department,
     sub_department:[]
  }; // <-- objects instead of arrays in the hashtable

  r[a.department].sub_department.push(...a.sub_department); //and add the subdepartment not the object itself
  return r;
 }, Object.create(null)));

console.log(result);

Alternatively you could build up a hashtable and the resulting array in parallel, thats how i would do that:

 const result = [], hash = {};

 for(const {department, sub_department} of arr){
   if(hash[department]){
     hash[department].push(...sub_department);
   } else {
     result.push({department, sub_department});
     hash[department] = sub_department;
  }
}

To also group the sub_departments its slightly more complicated. For that we would need a nested hashtable and a nested lookup:

 const exit = Symbol("exit");
 const result = [], hash = {};

 for(const {department, sub_department} of arr){
   if(!hash[department]){
     const sub = [];
     hash[department] = {[exit]: sub};
     result.push({department, sub_department: sub});
   }

   for(const {name, ...data} of sub_department){
     if(hash[department][name]){
       hash[department][name].push(data);
     } else {
       const subsub = [];
       hash[department][exit].push({name, subsub});
       hash[department][name] = subsub;
     }
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Sub department grouping is not working as expected with my desired result
0

A somewhat long-winded solution extending the previously posted solution:

var result = Object.values(arr.reduce(function(r, a) { //<--- the hashtable > array conversion
    r[a.department] = r[a.department] || {
        department: a.department,
        sub_department:[]
    }; // <-- objects instead of arrays in the hashtable

    if(r[a.department].sub_department.length>0){
        var index = r[a.department].sub_department.findIndex(function(sd){
            return sd.name === a.sub_department[0].name;
        });
        if(index!==-1){
            r[a.department].sub_department[index].application.push(a.sub_department[0].application[0]);
            return r;
        }
    }

    r[a.department].sub_department.push(...a.sub_department); //and add the sub department not the object itself
    return r;


  }, Object.create(null)));
    console.log(result);

Comments

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.