使用VanillaJS对group和filter以及对象数组进行分组

时间:2017-12-08 14:44:55

标签: javascript filtering grouping

我有下表包含一些对象:

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"
    }
];

我想要做的是使用对象属性"organizationId""organizationTitle"对这些对象进行分组,所以我尝试的是使用"organizationId"对其进行分组,如下所示:

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

这将生成一个带有键的对象,该键具有用于分组的每个"organizationId"的值,以及分组的数据作为其值。

然后我想为每个用于分组的"organizationId"创建一个对象,该对象将包含三个属性:id,其中"organizationId"的值为title"organizationTitle"具有rolesid的值,这是一个数组。

此数组将包含每个分组对象的对象,此对象将具有两个属性:"roleId",其title"roleTitle"的值将具有{{[ { 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' } ] } ] 的值1}}。

所以结果应该是这样的:

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);

所以我做了以下工作,这有效,我得到了预期的结果:

{{1}}

正如你所看到的,我为此使用了太多的代码,首先我使用了reduce函数,然后使用了forEeach,并使用了另一个forEach。

有没有一种简单的方法可以使用vanillaJS(ES5)并尽可能使用最小代码?

提前致谢。

3 个答案:

答案 0 :(得分:2)

您可以使用array#reduce来收集所有信息。

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);

答案 1 :(得分:1)

你可以用一个循环来完成这个:

 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}]
     });
  }
 }

答案 2 :(得分:0)

单次迭代的ES6:

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;
  }, {});