Vimalraj Selvam Vimalraj Selvam - 2 months ago 6
React JSX Question

Filtering, Grouping and Aggregating data using Underscore js

I have a raw data like this:

var data = {
"issues": [
{
"fields": {
"project": {
"key": "ProjectA"
},
"components": [
{
"name": "Component A"
},
{
"name": "Component C"
}
],
"priority": {
"name": "P0"
},
"status": {
"name": "Closed"
}
}
},
{
"fields": {
"project": {
"key": "ProjectA"
},
"components": [
{
"name": "Component B"
}
],
"priority": {
"name": "P1"
},
"status": {
"name": "Reopened"
}
}
},
{
"fields": {
"project": {
"key": "ProjectA"
},
"components": [
{
"name": "Component B"
}
],
"priority": {
"name": "P1"
},
"status": {
"name": "Closed"
}
}
},
{
"fields": {
"project": {
"key": "Project B"
},
"components": [
{
"name": "Component X"
}
],
"priority": {
"name": "P1"
},
"status": {
"name": "Closed"
}
}
}
]
};


If I give
ProjectA
as input, I would like to filter, group and aggregate the output as follows:

"components": [
{
"name": "Component A",
"priorities": [
{
"name": "P0",
"status": [
{
"name": "Open",
"count": 0
},
{
"name": "Reopened",
"count": 0
},
{
"name": "Closed",
"count": 1
}
]
},
{
"name": "P1",
"status": [
{
"name": "Open",
"count": 0
},
{
"name": "Reopened",
"count": 0
},
{
"name": "Closed",
"count": 0
}
]
}
]
},
{
"name": "Component B",
"priorities": [
{
"name": "P0",
"status": [
{
"name": "Open",
"count": 0
},
{
"name": "Reopened",
"count": 0
},
{
"name": "Closed",
"count": 0
}
]
},
{
"name": "P1",
"status": [
{
"name": "Open",
"count": 0
},
{
"name": "Reopened",
"count": 1
},
{
"name": "Closed",
"count": 1
}
]
}
]
},
{
"name": "Component C",
"priorities": [
{
"name": "P0",
"status": [
{
"name": "Open",
"count": 0
},
{
"name": "Reopened",
"count": 0
},
{
"name": "Closed",
"count": 1
}
]
},
{
"name": "P1",
"status": [
{
"name": "Open",
"count": 0
},
{
"name": "Reopened",
"count": 0
},
{
"name": "Closed",
"count": 0
}
]
}
]
}
]


I tried chaining, filtering, grouping, but not sure how to use this, since my data is too nested.

Answer

This is a proposal in plain javascript with first collecting all components and priorities and build then a result object and later increment the count of the status.

var data = { "issues": [{ "fields": { "project": { "key": "ProjectA" }, "components": [{ "name": "Component A" }, { "name": "Component C" }], "priority": { "name": "P0" }, "status": { "name": "Closed" } } }, { "fields": { "project": { "key": "ProjectA" }, "components": [{ "name": "Component B" }], "priority": { "name": "P1" }, "status": { "name": "Reopened" } } }, { "fields": { "project": { "key": "ProjectA" }, "components": [{ "name": "Component B" }], "priority": { "name": "P1" }, "status": { "name": "Closed" } } }, { "fields": { "project": { "key": "Project B" }, "components": [{ "name": "Component X" }], "priority": { "name": "P1" }, "status": { "name": "Closed" } } }] },
    componentsO = Object.create(null),
    prioritiesO = Object.create(null),
    components,
    priorities,
    status_ = ['Open', 'Reopened', 'Closed'], // status collides in chrome with window.status
    hash = Object.create(null),
    getKey = function (a) { return a.join('|'); },
    result = {};

data.issues.forEach(function (issue) {
    if (issue.fields.project.key === 'ProjectA') {
        issue.fields.components.forEach(function (component) {
            componentsO[component.name] = true;
        });
        prioritiesO[issue.fields.priority.name] = true;
    }
});

components = Object.keys(componentsO).sort();
priorities = Object.keys(prioritiesO).sort();

result.components = components.map(function (component) {
    return {
        name: component,
        priorities: priorities.map(function (priority) {
            return {
                name: priority,
                status: status_.map(function (status) {
                    var key = getKey([component, priority, status]);
                    hash[key] = { name: status, count: 0 };
                    return hash[key];
                })
            };
        })
    }
});

data.issues.forEach(function (issue) {
    if (issue.fields.project.key === 'ProjectA') {
        issue.fields.components.forEach(function (component) {
            var key = getKey([component.name, issue.fields.priority.name, issue.fields.status.name]);
            hash[key].count++;
        });
    }
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments