1

i have a simple object

var xobj = [
    { role:"Organize Admin", role_id:"id1", permission_name:"View All Users",active: "true" },
    { role:"Organize Admin", role_id:"id1", permission_name:"Create users", active: "true" },
    { role:"Organize Admin", role_id:"id1", permission_name:"Edit users", active: "true" },
    { role:"System Admin", role_id:"id2", permission_name:"Edit users", active: "true" },
    { role:"System Admin", role_id:"id2", permission_name:"Edit users", active: "true" },
];

i am struggling to restructure object based on role_id while grouping permissions for each role_id

i want something like this

What is the efficient way to achieve this ?

3 Answers 3

4

Use .reduce to group the role objects, and use .find inside to find the matching id object in the accumulator array (if it exists):

const input = [
  { role:"Organize Admin", role_id:"id1", permission_name:"View All Users",active: "true" },
  { role:"Organize Admin", role_id:"id1", permission_name:"Create users", active: "true" },
  { role:"Organize Admin", role_id:"id1", permission_name:"Edit users", active: "true" },
  { role:"System Admin", role_id:"id2", permission_name:"Edit users", active: "true" },
  { role:"System Admin", role_id:"id2", permission_name:"Edit users", active: "true" },
];
const roles = input.reduce((a, { role_id, permission_name: name, active }) => {
  const foundRole = a.find(({ id }) => id === role_id);
  if (foundRole) foundRole.permissions.push({ name, active });
  else a.push({ id: role_id, permissions: [{ name, active }] });
  return a;
}, []);
console.log(roles);

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

Comments

1

Another way of doing this is using an object and accumulate content into its properties

var xobj = [
    { role:"Organize Admin", role_id:"id1", permission_name:"View All Users",active: "true" },
    { role:"Organize Admin", role_id:"id1", permission_name:"Create users", active: "true" },
    { role:"Organize Admin", role_id:"id1", permission_name:"Edit users", active: "true" },
    { role:"System Admin", role_id:"id2", permission_name:"Edit users", active: "true" },
    { role:"System Admin", role_id:"id2", permission_name:"Edit users", active: "true" },
];
var groups = {};
xobj.forEach(obj => {	
    if(!groups.hasOwnProperty(obj.role_id)){
        groups[obj.role_id] = [];
    }
    groups[obj.role_id].push(obj);
})
console.log(groups)

Comments

0

Here is another solution:

Search for the unique key used to group by. If it doesn't exist, add it and assign an array to it with the current value. Otherwise append the current item to the existing key.

var xobj = [{
    role: "Organize Admin",
    role_id: "id1",
    permission_name: "View All Users",
    active: "true"
  },
  {
    role: "Organize Admin",
    role_id: "id1",
    permission_name: "Create users",
    active: "true"
  },
  {
    role: "Organize Admin",
    role_id: "id1",
    permission_name: "Edit users",
    active: "true"
  },
  {
    role: "System Admin",
    role_id: "id2",
    permission_name: "Edit users",
    active: "true"
  },
  {
    role: "System Admin",
    role_id: "id2",
    permission_name: "Edit users",
    active: "true"
  },
];




const groupedData = xobj.reduce((acc, x) => {
  const index = acc.findIndex(y => Object.keys(y)[0] === x.role_id)
  if (index < 0) {
    acc.push({
      [x.role_id]: [x]
    });
    return acc;
  }
  acc[index] = {
    ...acc[index],
    [x.role_id]: [...acc[index][x.role_id], x]
  }
  return acc;
}, [])

console.log(groupedData);

Also when having a list/array, name your variable to indicate that it's indeed a list/array instead of xobj in your case.

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.