bspckl bspckl - 23 days ago 11
Javascript Question

Javascript: Adding 0 values to arrays of different sizes

Quite complicated to explain so I will try to be explicit.

I have an object, data, which is an array of objects that includes an array of objects and a string:

var groups = [
{
bars: [
{label: 'a', value: 28},
{label: 'c', value: 16}
],
string: 'one'
},
{
bars: [
{label: 'a', value: 3},
{label: 'b', value: 17},
{label: 'c', value: 24}
],
string: 'two'
},
{
bars: [
{label: 'a', value: 12},
{label: 'd', value: 7},
{label: 'e', value: 36}
],
string: 'three'
},
{
bars: [
{label: 'c', value: 32},
{label: 'e', value: 2}
],
string: 'four'
}
]


I need all "bars" objects to be the same size and have a 0 value if the object for said label does not exist. As you can see, the label key associated with "bars" is a finite list. My main problem here is that the size of the "groups" object as well as the size of the "bars" object is dynamic. With underscore, I have used:

var labelNames = _.uniq(_.flatten
(_.map(data.groups,function(groups) {
return _.pluck(groups.bars, 'label');
})));


to extract the list of known labels giving me

['a', 'b', 'c', 'd', 'e']


I now want to map this array to the bars object giving me this output:

var groups = [
{
bars: [
{label: 'a', value: 28},
{label: 'b', value: 0},
{label: 'c', value: 16},
{label: 'd', value: 0},
{label: 'e', value: 0}
],
string: 'one'
},
{
bars: [
{label: 'a', value: 3},
{label: 'b', value: 17},
{label: 'c', value: 24},
{label: 'd', value: 0},
{label: 'e', value: 0}
],
string: 'two'
},
{
bars: [
{label: 'a', value: 12},
{label: 'b', value: 0},
{label: 'c', value: 0},
{label: 'd', value: 7},
{label: 'e', value: 36}
],
string: 'three'
},
{
bars: [
{label: 'a', value: 0},
{label: 'b', value: 0},
{label: 'c', value: 32},
{label: 'd', value: 0},
{label: 'e', value: 2}
],
string: 'four'
}
]


If helpful, I must have even bars because I have created a highcharts series with these objects like this example.
I hope that makes sense. Any help would be appreciated. I've been going crazy trying to figure this out.

EDIT: Here's what I went with for those who stumble on this.

_.each(data.groups, function(group) {
var currentValues = _.pluck(group.bars, 'label');
var zeroValues = _.difference(labelNames, currentValues);
_.each(zeroValues, function(newLabel) {
group.bars.push({label: newLabel, value: 0});
});
});

Answer

This should do the trick:

// First, iterate over each group
for (var i = 0; i < groups.length; i++) {

    var bars = groups[i].bars;

    // Second, iterate over each of the previously collected labels, e.g. var labels = ['a', 'b', 'c', 'd', 'e']
    for (var j = 0; j < labels.length; j++) {

        // Assume label does not exist, until proven otherwise
        var labelDoesNotExist = true;

        // Third, iterate over the bars' existing labels
        for (var k = 0; k < bars.length; k++) {

            var label = bars[k].label;

            // Check if the label matches the current iteration of pre-collected labels
            if (label == labels[j]) {
                labelDoesNotExist = false;
            }
        }

        // If no existing label matches any of the pre-collected labels, then create a new label with value of 0
        if (labelDoesNotExist) {
            bars.push({
                'label': labels[j],
                'value': '0'
            });
        }
    }
}
Comments