1

I have an array of objects as following

[
0: {department_ID: 6, department_Name: "Management", section_ID: 12, section_Name: "General Management", employee_ID: 1, …}
1: {department_ID: 6, department_Name: "Management", section_ID: 12, section_Name: "General Management", employee_ID: 2, …}
2: {department_ID: 1, department_Name: "HR & Admin", section_ID: 20, section_Name: "HR and Admin", employee_ID: 90, …}
   ...
]

What I want to achieve is to group values in an array by order same department_ID > same section_ID and finally employee data like this

[
  {
    department_ID: 6,
    department_Name: "Management",
    children: [
      {
        section_ID: 12,
        section_Name: "General Management",
        children: [
          {
            employee_ID: 1,
            employee_Name: "",
          },
          {
            employee_ID: 2,
            employee_Name: "",
          },
        ],
      },
    ],
  },
  {
    department_ID: 1,
    department_Name: "HR & Admin",
    children: [
      {
        section_ID: 20,
        section_Name: "HR and Admin",
        children: [
          {
            employee_ID: 90,
            employee_Name: "",
          },
        ],
      },
    ],
  },
];

I've tried

function getUnique() {
  var hashObject = {};
  let obj = {};

  treeviewApiValues.forEach(function (elem) {
    var key = elem.department_ID;
    if (hashObject[key]) {
      hashObject[key] = {
        id: elem.department_ID,
        name: elem.department_Name,
        children: checkSectionID(elem),
      };
    } else {
      hashObject[key] = {
        id: elem.department_ID,
        name: elem.department_Name,
        children: checkSectionID(elem),
      };
    }
  });

  function checkSectionID(elem) {
    const key = elem.department_ID;

    if (obj[key]) {
      obj[key].push({
        id: elem.section_ID,
        name: elem.section_Name,
      });
    } else {
      obj[key] = [
        {
          id: elem.section_ID,
          name: elem.section_Name,
        },
      ];
    }

    var desiredArray2 = Object.values(obj);

    return desiredArray2;
  }

  var desiredArray = Object.values(hashObject);
}

This is a messy function, but I get

[
0: {department_ID: 1, department_Name: "HR & Admin", children: Array(7)}
1: {department_ID: 2, department_Name: "ELV Systems Installation & Service", children: Array(7)}
]

Children array is something wrong and not having array of same department_ID and I also need to get the employee data under same section_ID. If anyone could help me, i would be so much appreciated.

Full code can be found here https://codesandbox.io/s/gracious-voice-bbmsy?file=/src/App.js

3 Answers 3

1

You could take a nested approach with an array for the grouping levels.

This solution removes unwanted properties from the object and pushes the final object to the most nested children array.

This solution works for an arbitrary count of levels.

const
    data = [{ department_ID: 6, department_Name: "Management", section_ID: 12, section_Name: "General Management", employee_ID: 1 }, { department_ID: 6, department_Name: "Management", section_ID: 12, section_Name: "General Management", employee_ID: 2 }, { department_ID: 1, department_Name: "HR & Admin", section_ID: 20, section_Name: "HR and Admin", employee_ID: 90 }],
    groups = [['department_ID', 'department_Name'], ['section_ID', 'section_Name']],
    result = data.reduce((r, o) => {
        groups
            .reduce((group, keys) => {
                let temp = group.find(q => q[keys[0]] === o[keys[0]]);
                if (!temp) group.push(temp = { ...Object.fromEntries(keys.map(k => [k, o[k]])), children: [] });
                keys.forEach(k => ({ [k]: _, ...o} = o));
                return temp.children;
            }, r)
            .push(o);
        return r;
    }, []);

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

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

2 Comments

This is exactly what I needed ! Thanks a lot. One thing though is when I test, _ is showing undefined. I think you forgot to add keys.forEach((k, _) => ..), thanks anyway
no, because _ is a placeholder for a named property which is not needed anymore.
1

May be it solve your task

let list = [
    {department_ID: 6, department_Name: "Management", section_ID: 12, section_Name: "General Management", employee_ID: 1, …},
    {department_ID: 6, department_Name: "Management", section_ID: 12, section_Name: "General Management", employee_ID: 2, …},
    {department_ID: 1, department_Name: "HR & Admin", section_ID: 20, section_Name: "HR and Admin", employee_ID: 90, …}
    ...
];

let vals = [];
list.map(v=>{
    vals[v.department_ID] || (vals[v.department_ID] = {
        department_ID: v.department_ID,
        department_Name: v.department_Name,
        children: []
    });

    vals[v.department_ID].children[v.section_ID] || 
    (vals[v.department_ID].children[v.section_ID] = {
        section_ID: v.section_ID,
        section_Name: v.section_Name,
        children: []
    });

    vals[v.department_ID].children[v.section_ID].children.push({
        employee_ID: v.employee_ID,
        employee_Name: v.employee_Name
    });

});

vals = vals.filter(e=>!!e);
let result = vals.map(e=>{
    e.children = e.children.filter(v=>!!v);
    return e;
});

Comments

0

You can use reduce() and find() as follows:

const arr = [
  {department_ID: 6, department_Name: "Management", section_ID: 12, section_Name: "General Management", employee_ID: 1, employee_name: 'john'},
  {department_ID: 6, department_Name: "Management", section_ID: 12, section_Name: "General Management", employee_ID: 2, employee_name: 'avi'},
  {department_ID: 1, department_Name: "HR & Admin", section_ID: 20, section_Name: "HR and Admin", employee_ID: 90, employee_name: 'jennifer'}
]

const res = arr.reduce((acc, curr) => {
  const obj = acc.find(item => item.department_ID === curr.department_ID && item?.children[0]?.section_ID === curr.section_ID);
  if(obj) {
    obj.children[0].children.push({ employee_ID: curr.employee_ID, employee_name: curr.employee_name});
  } else {
    acc.push({
      department_ID: curr.department_ID,
      department_Name: curr.department_Name,
      children: [
        {
          section_ID: curr.section_ID,
          section_Name: curr.section_Name,
          children: [{
            employee_ID: curr.employee_ID,
            employee_name: curr.employee_name
          }]
        }
      ]
    })
  }

  return acc;
}, []);

console.log(res);

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.