jdmarlon
jdmarlon

Reputation: 63

Grouping / counting in javascript using underscore.js

I am new to javascript (and to Stack Overflow) and I've encountered a problem I can't seem to solve. I am trying to generate a simple pie chart that shows the number of Projects for each value of Technology in my data. This is the kind of data I am working with:

The pie ratio in the example above would be 2:1:1.

The first part of my code loads the data and pushes it to an array, "techArray", that contains [project, tech]. This part works ok - I've verified it in a simplified version of the code.

I then want to group the array "techArray" and count the instances of each tech. To do so I'm using the Underscore library, as follows:

var chartData = [];
var techData = _.groupBy(techArray, 'tech');
_.each(techData, function(row) {
    var techCount = row.length;
    chartData = push( {
        name: row[0].tech,
        y: techCount
    });
});

The script then renders the chartData array using highcharts. Again, I have verified that this section works using a simplified (ungrouped) version.

There must be an issue with the grouping/counting step outlined above because I am seeing no output, but I simply can't find where. I am basing my solution on the following worked example: Worked example.

If anyone can spot the error in what I've written, or propose another way of grouping the array, I'd be very grateful. This seems like it should be a simpler task than it's proving to be.

Upvotes: 6

Views: 12847

Answers (2)

Gruff Bunny
Gruff Bunny

Reputation: 27976

countBy could be used instead of groupBy:

var techArray = [
    { project: 'Project1', tech: 'Java'},
    { project: 'Project2', tech: 'Excel'},
    { project: 'Project3', tech: 'SAS'},
    { project: 'Project4', tech: 'Java'},
];

var counts = _.countBy(techArray,'tech');

This will return an object with the tech as properties and their value as the count:

{ Java: 2, Excel: 1, SAS: 1 }

To get the data in the form for highcharts use map instead of each:

var data = _.map(counts, function(value, key){
    return {
        name: key,
        y: value
    };
});

Upvotes: 22

Jonathan Lerner
Jonathan Lerner

Reputation: 450

This should work

var techArray = [['Project1','Java'], ['Project2', 'excel'], ['Project3', 'Java']];

var chartData = [];
var techData = _.groupBy(techArray, function(item) {
    return item[1];
});
_.each(techData, function(value, key) {
    var techCount = value.length;
    chartData.push({
        name: key,
        y: techCount
    });
});

_.groupBy needs to either get a property name, or a function that returns the value being grouped. There is no tech property of an array, so you cant group by it. But, as our techArray is an array of tuples, we can pass a function _.groupBy that returns the value that we want to groupBy, namely the second item in each tuple.

chartData now looks like this:

[{
    name: 'Java',
    y: 2
}, {
    name: 'excel',
    y: 1
}]

Upvotes: 0

Related Questions