swennemen
swennemen

Reputation: 955

Manipulate array of objects to new array with average number.

I have a array that I want to manipulate because I need to use it as a datasource for D3.js. An example of this dataset would be:

var data =  [
 {day: 1, month: 1,  length: 100,  year: 2010},
 {day: 2, month: 1,  length: 125,  year: 2010},
 {day: 3, month: 1,  length: 150,  year: 2010},
 {day: 4, month: 1,  length: 175,  year: 2010},
 {day: 1, month: 2,  length: 225,  year: 2010},
 {day: 2, month: 2,  length: 250,  year: 2010},
 {day: 3, month: 2,  length: 325,  year: 2010},

 {day: 1, month: 1,  length: 225,  year: 2011},
 {day: 1, month: 1,  length: 150,  year: 2011},
 {day: 1, month: 1,  length: 190,  year: 2011},
 {day: 1, month: 2,  length: 210,  year: 2011},
 {day: 2, month: 2,  length: 110,  year: 2011},
 {day: 3, month: 2,  length: 160,  year: 2011},
 {day: 4, month: 2,  length: 190,  year: 2011},
]

In this case I want to create a new array, with two arrays that hold the average length of a month. For example:

var newData = [ [137.5, 266.7], [183.33, 167.5] ]

Where newData[0][1] would be the average length of month 1 in year 2010.

I have some problems incorporating this in a nice way. I can create the sum of the length, but dividing the sum is difficult. The code I have is:

data.forEach(function (el) {
   for (var j = 0; j <= 3; j++) {
     if (el.year === 2010 + j) {
       for (var i = 1; i <= 2; i++) {
                if (el.month === i) {
                    var oldLength = dataNew[j][i - 1] || 0;
                    var newLength = el.length + oldLength;
                    dataNew[j][i - 1] = newLength;
                }
        }
     }
   }
});

How would this function could be adjusted so it saves the average instead of the sum in newData.

Upvotes: 2

Views: 61

Answers (1)

ahmohamed
ahmohamed

Reputation: 2970

You can use d3.js itself for facilitate you job and make your code more readable. Using d3.nest()

var data =  [
 {day: 1, month: 1,  length: 100,  year: 2010},
 {day: 2, month: 1,  length: 125,  year: 2010},
 {day: 3, month: 1,  length: 150,  year: 2010},
 {day: 4, month: 1,  length: 175,  year: 2010},
 {day: 1, month: 2,  length: 225,  year: 2010},
 {day: 2, month: 2,  length: 250,  year: 2010},
 {day: 3, month: 2,  length: 325,  year: 2010},

 {day: 1, month: 1,  length: 225,  year: 2011},
 {day: 1, month: 1,  length: 150,  year: 2011},
 {day: 1, month: 1,  length: 190,  year: 2011},
 {day: 1, month: 2,  length: 210,  year: 2011},
 {day: 2, month: 2,  length: 110,  year: 2011},
 {day: 3, month: 2,  length: 160,  year: 2011},
 {day: 4, month: 2,  length: 190,  year: 2011},
]

var nest = d3.nest()
    .key(function(d){return d.year})
    .key(function(d){return d.month})
    .rollup(function(d){
        return d3.mean(d, function(g){return g.length});
    })
    .entries(data)

console.log(nest[0].values[0]) // 137.5

Here is a working fiddle

Upvotes: 3

Related Questions