JasonMHirst
JasonMHirst

Reputation: 576

Trying to understand _Underscore library

Having a hard time getting my head around the _Underscore library, the basics I think I'm picking up, but I think it's the terminology that is giving me problems.

For example I have the following Object:

CA3 "BAA"
vol_2007 0.15
vol_2008 0.2
vol_2009 0.25
vol_2010 0.3
vol_2011 0.600

CA3 "LUF"
vol_2007 1.13
vol_2008 0.4
vol_2009 1.6
vol_2010 2.8
vol_2011 0.43

I've arrived at this with the following:

var fieldtogroup = 'CA3';

var groups = _.groupBy(tmp,function (name) { return name[fieldtogroup] });
var sums = _.map(groups, function (group) {
    return _.reduce(group, function (a, b) { return b; }, 0);
});

The first problem I have is that if I use:

return _.reduce(group, function (a, b) { return a + b; }, 0);

I get an Object back of rubbish, I can see that the _Underscore documentation explains perfect that the 'a' is the current value and the 'b' is the new, but this just doesn't work. Can someone explain why this is? Do I need a clause within the function to determine if the values are numeric before doing the calculation?

Also, ultimately, I want to be able to return an array of objects similar to:

vol_2007: 0.15,1.13
vol_2008: 0.2,0.4
vol_2009: 0.25, 1.6
vol_2010: 0.3, 2.8
vol_2011: 0.600,0.43

I've managed to do this by 'kinda' rotating the Object, going through the array several times and pushing values into another array but I'm positive _Underscore would be able to do this for me yet I can't understand how.

If someone can enlighten me on these I'd really appreciate it, I've grasped the basics of the library but this has me stumped!

Worked out the last problem with the _.pluck command which is wonderful, but still getting errors when using the Reduce.

enter image description here

The 'more' simply contains values for vol_2009 -> vol_2011

Upvotes: 1

Views: 126

Answers (1)

Bergi
Bergi

Reputation: 665456

You are applying the sum-reduction on the wrong objects. See what your groups = _.groupBy(tmp, 'CA3') returns:

{ // arrays of objects grouped by their CA3 property:
    BAA: [
        {
            CA3: "BAA",
            vol_2007: 0.15
            …
        },
        …
    ],
    Rum: [
        {
            CA3: "Rum",
            …
        }, {
            CA3: "Rum",
            …
        },
        …
    ],
    …
}

You can't sum those objects.

Instead, you seem to want to group the property values of the objects in those arrays again by their property names:

byCAandVol = _.map(groups, function(arr) {
    var res = {};
    for (var i=0; i<arr.length; i++)
        for (var prop in arr[i])
            if (prop != "CA3")
                if (prop in res)
                    res[prop].pus(arr[i][prop]);
                else
                    res[prop] = [arr[i][prop]];
    return res;
});

This is a bit like a group-by-each-property. Now you've got

{ // arrays of objects grouped by their CA3 property:
    BAA: {
        vol_2007: [0.15, …],
        vol_2008: […]
        …
    },
    Rum: {
        vol_2007: …
    },
    …
}

Now you can sum those arrays with your reduce function, wrapped in two mappings:

sumsByCAandVol = _.map(byCAandVol, function (group) {
    return _.map(group, function(vols) {
        return _.reduce(vols, function (a, b) { return a + b; }, 0);
    });
});

Or, you don't do that in an extra step and build sums instead of arrays right in the group-by-each-property function.

Upvotes: 2

Related Questions