1

I have the following table which contains some objects :

var data = [
    {
        "userRoleId": 1,
        "userId": 1,
        "roleId": 1,
        "organizationId": "ORG_01",
        "roleTitle": "Admin",
        "organizationTitle": "Organization 01",
        "startDate": "2017-11-15",
        "endDate": "2017-11-15",
        "automatic": false,
        "useDate": "2017-11-15"
    },
    {
        "userRoleId": 2,
        "userId": 1,
        "roleId": 2,
        "organizationId": "ORG_01",
        "roleTitle": "Agent",
        "organizationTitle": "Organization 01",
        "startDate": "2017-11-15",
        "endDate": "2017-11-15",
        "automatic": true,
        "useDate": "2017-11-15"
    },
    {
        "userRoleId": 4,
        "userId": 1,
        "roleId": 4,
        "organizationId": "ORG_02",
        "roleTitle": "Referent",
        "organizationTitle": "Organization 02",
        "startDate": "2017-11-15",
        "endDate": "2017-11-15",
        "automatic": true,
        "useDate": "2017-11-15"
    },
    {
        "userRoleId": 5,
        "userId": 1,
        "roleId": 2,
        "organizationId": "ORG_02",
        "roleTitle": "Agent",
        "organizationTitle": "Organization 02",
        "startDate": "2017-11-15",
        "endDate": "2017-11-15",
        "automatic": true,
        "useDate": "2017-11-15"
    }
];

What I want to do is to group these objects using the object property "organizationId" and "organizationTitle", so what I tried is I grouped them using "organizationId" as following :

var filtered = data.reduce(function(accumulator, currentValue) {
    (accumulator[currentValue['organizationId']] = accumulator[currentValue['organizationId']] || []).push(currentValue);
    return accumulator;
  }, {});

This will generate an object with a key which has the value of each "organizationId" used for grouping, and the grouped data as it's value.

Then I want to create an object for each "organizationId" used for grouping which will have three properties: id which will have the value for "organizationId", title which will have the value for "organizationTitle" and roles which is an array.

This array will contain objects for each grouped objects, this object will have two properties: id which will have the value for "roleId" and title which will have the value for "roleTitle".

So the result should look like this:

[
    { 
        id: 'ORG_01',
        lib: 'Organization 01',
        roles: [
            {
                id: 1,
                title: 'Admin'
            },
            {
                id: 2,
                title: 'Agent'
            }
        ] 
    },
      { 
        id: 'ORG_02',
        lib: 'Organization 02',
        roles: [
            {
                id: 4,
                title: 'Referent'
            },
            {
                id: 2,
                title: 'Agent'
            }
        ] 
    }
]

So I did the following, which works and I get the expected result :

var organizations = [];

for(var i in filtered){
    var obj = {};
    obj.id = i;

    var roles = [];
    filtered[i].forEach(function(el){
        roles.push({'id' : el.roleId, 'lib': el.roleTitle})
        obj.lib = el.organizationTitle;
    });
    obj.roles = roles;
    organizations.push(obj);
}

console.log(organizations);

As you can see I used too much code for this, first I used the reduce function then a forEeach and inisde it another forEach.

Isn't there a simple way doing that using vanillaJS (ES5) with the minimun code possible ?

Thanks in advance.

3 Answers 3

2

You can use array#reduce to club all your information.

var data = [ { "userRoleId": 1, "userId": 1, "roleId": 1, "organizationId": "ORG_01", "roleTitle": "Admin", "organizationTitle": "Organization 01", "startDate": "2017-11-15", "endDate": "2017-11-15", "automatic": false, "useDate": "2017-11-15" }, { "userRoleId":2, "userId": 1, "roleId": 2, "organizationId": "ORG_01", "roleTitle": "Agent", "organizationTitle": "Organization 01", "startDate": "2017-11-15", "endDate": "2017-11-15", "automatic": true, "useDate": "2017-11-15" }, { "userRoleId": 4, "userId": 1, "roleId":4, "organizationId": "ORG_02", "roleTitle": "Referent", "organizationTitle": "Organization 02", "startDate": "2017-11-15", "endDate": "2017-11-15", "automatic": true, "useDate": "2017-11-15" }, { "userRoleId": 5, "userId": 1, "roleId": 2, "organizationId":"ORG_02", "roleTitle": "Agent", "organizationTitle": "Organization 02", "startDate": "2017-11-15", "endDate": "2017-11-15", "automatic": true, "useDate": "2017-11-15" } ];

var result = data.reduce(function(r, o){
  r[o.organizationId] = r[o.organizationId] || {id : o.organizationId, lib : o.organizationTitle, roles : []};
  r[o.organizationId].roles.push({id : o.roleId, title: o.roleTitle});
  return r;
},{});
var output = Object.values(result);
console.log(output);

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

2 Comments

Thanks saved me a lot of bytes x-)
Glad to help you :)
1

You could do this with one loop:

 const result = [], hash = {};

 for(const {roleTitle : role, organizationId : id, organizationTitle : title, userId} of data){
   const key = id+"#"+title;
   if(hash[key]){
     hash[key].roles.push({ id: userId, role });
   } else {
     result.push(hash[key] = {
        id, title, roles : [{ id : userId, role}]
     });
  }
 }

Comments

0

ES6 with single iteration:

const newData = data.reduce(
  (obj, { organizationId: id, organizationTitle: lib, roleId, roleTitle }) => {
    obj[id] = obj[id] || { id, lib, roles: [] };
    obj[id].roles.push({ id: roleId, title: roleTitle });
    return obj;
  }, {});

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.