r mk r r mk r - 4 days ago 6
Javascript Question

Grouping the elements of an object. (underscore.js)

I have an object as shown below :

[
{"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"}
]


I need to group it like this :

[
[
[
{"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"}]
]
]


I am using
underscore.js
to group the elements in the object.

$scope.InitController = function () {

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


The output from the above code looks like :

[
[
{"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"}]
]


What do I need to do in order to get the desired output as shown above.

Your code producing the output in the below shown form :

[
[
{"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"}]
]

Answer

Here's a very simple function to do it in vanilla JavaScript, it takes two arguments:
arr The array containing the objects that you want to group.
properties An array of strings with the names of the properties you want to group the objects by, ordered by priority (objects will be ordered by the first property in the array, then the second, etc).

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

You would use it as follows:

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"]));
Comments