对对象的元素进行分组。 (underscore.js)

时间:2016-11-28 20:36:46

标签: javascript angularjs underscore.js

我有一个如下所示的对象:

[
{"ClientGroupName":"ABC","CompanyName":"AA","ControlGroupName":"1"},
{"ClientGroupName":"ABC","CompanyName":"BB","ControlGroupName":"1"},
{"ClientGroupName":"ABC","CompanyName":"CC","ControlGroupName":"1"},
{"ClientGroupName":"ABC","CompanyName":"DD","ControlGroupName":"2"},
{"ClientGroupName":"ABC","CompanyName":"EE","ControlGroupName":"3"},
{"ClientGroupName":"DEF","CompanyName":"FF","ControlGroupName":"1"},
{"ClientGroupName":"DEF","CompanyName":"GG","ControlGroupName":"1"},
{"ClientGroupName":"DEF","CompanyName":"HH","ControlGroupName":"2"}
]

我需要像这样分组:

 [    
    [
        [
         {"ClientGroupName":"ABC","CompanyName":"AA","ControlGroupName":"1"},
         {"ClientGroupName":"ABC","CompanyName":"BB","ControlGroupName":"1"},
         {"ClientGroupName":"ABC","CompanyName":"CC","ControlGroupName":"1"}
        ],
        [{"ClientGroupName":"ABC","CompanyName":"DD","ControlGroupName":"2"}],
        [{"ClientGroupName":"ABC","CompanyName":"EE","ControlGroupName":"3"}]
    ],
    [
        [
         {"ClientGroupName":"DEF","CompanyName":"FF","ControlGroupName":"1"},
         {"ClientGroupName":"DEF","CompanyName":"GG","ControlGroupName":"1"}
        ],
        [{"ClientGroupName":"DEF","CompanyName":"HH","ControlGroupName":"2"}]
    ]    
]

我正在使用underscore.js对对象中的元素进行分组。

 $scope.InitController = function () {      

   ClientGroupService.GetClientGroupList().then(function (response) {    
    $scope.groupByTwoFields = [];
    $scope.groupByTwoFields = _.groupBy(response.data, function (obj) {
                    return obj.ClientGroupName  + '|' + obj.ControlGroupName;
                });
       .....
   });
};

上面代码的输出如下:

[   
        [
         {"ClientGroupName":"ABC","CompanyName":"AA","ControlGroupName":"1"},
         {"ClientGroupName":"ABC","CompanyName":"BB","ControlGroupName":"1"},
         {"ClientGroupName":"ABC","CompanyName":"CC","ControlGroupName":"1"}
        ],
        [{"ClientGroupName":"ABC","CompanyName":"DD","ControlGroupName":"2"}],
        [{"ClientGroupName":"ABC","CompanyName":"EE","ControlGroupName":"3"}],  
        [
         {"ClientGroupName":"DEF","CompanyName":"FF","ControlGroupName":"1"},
         {"ClientGroupName":"DEF","CompanyName":"GG","ControlGroupName":"1"}
        ],
        [{"ClientGroupName":"DEF","CompanyName":"HH","ControlGroupName":"2"}]   
]

如上所示,我需要做什么才能获得所需的输出。

您的代码以下面显示的格式生成输出:

  [ 
        [
         {"ClientGroupName":"ABC","CompanyName":"AA","ControlGroupName":"1"},
         {"ClientGroupName":"ABC","CompanyName":"BB","ControlGroupName":"1"},
         {"ClientGroupName":"ABC","CompanyName":"CC","ControlGroupName":"1"},
         {"ClientGroupName":"ABC","CompanyName":"DD","ControlGroupName":"2"},
         {"ClientGroupName":"ABC","CompanyName":"EE","ControlGroupName":"3"}
        ],  
        [
         {"ClientGroupName":"DEF","CompanyName":"FF","ControlGroupName":"1"},
         {"ClientGroupName":"DEF","CompanyName":"GG","ControlGroupName":"1"},
        {"ClientGroupName":"DEF","CompanyName":"HH","ControlGroupName":"2"}]    
]

4 个答案:

答案 0 :(得分:2)

我只用vanillaJS做了以防上述答案对你不起作用:

var data = [

        {"ClientGroupName":"ABC","CompanyName":"AA","ControlGroupName":"1"},

        {"ClientGroupName":"ABC","CompanyName":"BB","ControlGroupName":"1"},

        {"ClientGroupName":"ABC","CompanyName":"CC","ControlGroupName":"1"},

        {"ClientGroupName":"ABC","CompanyName":"DD","ControlGroupName":"2"},

        {"ClientGroupName":"ABC","CompanyName":"EE","ControlGroupName":"3"},

        {"ClientGroupName":"DEF","CompanyName":"FF","ControlGroupName":"1"},

        {"ClientGroupName":"DEF","CompanyName":"GG","ControlGroupName":"1"},

        {"ClientGroupName":"DEF","CompanyName":"HH","ControlGroupName":"2"}

    ];



    var ClientGroupNames = [];

    data.forEach(function(o){

        if(ClientGroupNames.indexOf(o.ClientGroupName) < 0){

            ClientGroupNames.push(o.ClientGroupName);

        }

    });

    var result = ClientGroupNames.map(function(name){

        return data.filter(function(comp){

            return comp.ClientGroupName == name ? true : false;

        })

    }).map(function(grp){

        var groupNames = [];

        grp.forEach(function(company){

            if(groupNames.indexOf(company.ControlGroupName) < 0)

                groupNames.push(company.ControlGroupName);

        })

        return groupNames.map(function(name){

            return grp.filter(function(gp){

                return gp.ControlGroupName == name ? true : false;

            })

        })
    })

答案 1 :(得分:2)

_.groupBy不返回数组,它返回一个对象。

   var data = [{
  "ClientGroupName": "ABC",
  "CompanyName": "AA",
  "ControlGroupName": "1"
}, {
  "ClientGroupName": "ABC",
  "CompanyName": "BB",
  "ControlGroupName": "1"
}, {
  "ClientGroupName": "ABC",
  "CompanyName": "CC",
  "ControlGroupName": "1"
}, {
  "ClientGroupName": "ABC",
  "CompanyName": "DD",
  "ControlGroupName": "2"
}, {
  "ClientGroupName": "ABC",
  "CompanyName": "EE",
  "ControlGroupName": "3"
}, {
  "ClientGroupName": "DEF",
  "CompanyName": "FF",
  "ControlGroupName": "1"
}, {
  "ClientGroupName": "DEF",
  "CompanyName": "GG",
  "ControlGroupName": "1"
}, {
  "ClientGroupName": "DEF",
  "CompanyName": "HH",
  "ControlGroupName": "2"
}];

var obj = _.groupBy(data,function (obj) {
    return obj.ClientGroupName;
}); // groupBy returns an object, not a array
var result = Object.keys(obj).map(function (key) { return obj[key]; }); // this converts the object to an array

_.each(result,function(obj,index){ // loop through each item in the array
  var _obj = _.groupBy(obj,function(obj2){
    return obj2.ControlGroupName;
  }); // group it by the ControlBroupName and convert it to a array
  result[index] = Object.keys(_obj).map(function (key) { return _obj[key]; });

});

console.log("result:\n", result);

答案 2 :(得分:2)

这是一个非常简单的函数,在vanilla JavaScript中执行它,它有两个参数:
arr包含要分组的对象的数组 properties一个字符串数组,其中包含要按对象分组的属性的名称,按优先级排序(对象将按数组中的第一个属性排序,然后是第二个属性等)。

function groupByProperties(arr, properties) {
    const groups = {
        root: {
            array: [],
            children: {}
        }
    };

    arr.forEach(obj => {
        let group = groups.root;
        properties.forEach(propertyKey => {
            const property = obj[propertyKey];
            if (!group.children.hasOwnProperty(property)) {
                const child = {
                    array: [],
                    children: {}
                }
                group.array.push(child.array);
                group.children[property] = child;
            }
            group = group.children[property];
        });
        group.array.push(obj);
    });
    return groups.root.array;
}

您可以按如下方式使用它:

let data = [
    {"ClientGroupName":"ABC","CompanyName":"AA","ControlGroupName":"1"},
    {"ClientGroupName":"ABC","CompanyName":"BB","ControlGroupName":"1"},
    {"ClientGroupName":"ABC","CompanyName":"CC","ControlGroupName":"1"},
    {"ClientGroupName":"ABC","CompanyName":"DD","ControlGroupName":"2"},
    {"ClientGroupName":"ABC","CompanyName":"EE","ControlGroupName":"3"},
    {"ClientGroupName":"DEF","CompanyName":"FF","ControlGroupName":"1"},
    {"ClientGroupName":"DEF","CompanyName":"GG","ControlGroupName":"1"},
    {"ClientGroupName":"DEF","CompanyName":"HH","ControlGroupName":"2"}
];

console.log(groupByProperties(data, ["ClientGroupName", "ControlGroupName"]));

答案 3 :(得分:1)

您必须groupBy两次:

result = _(data).groupBy('ClientGroupName').map(g =>
    _.values(_.groupBy(g, 'ControlGroupName'))
).value()