Reputation: 4919
I have data that comes from my server to datatables. I'm successfully populating my table but in footer callback I want to do some statistics.
Lets say I have data like so:
var data = [{
date: '2013-05-12',
holiday: "One type of holiday",
dayType: "Weekend"
}, {
date: '2013-05-13',
holiday: "Another type",
dayType: "Weekend"
}, {
date: '2013-05-14',
holiday: "Another type",
dayType: "Work"
}, {
date: '2013-05-15',
holiday: "",
dayType: "Work"
}];
I would like to count number of days with different holidays.
Here is result I would like to get:
var summary= [
{
"One type of holiday": {
"work": 0,
"weekend": 1
}
},
{
"Another type": {
"work": 1,
"weekend": 1
}
}];
I've created a very simple code to simply aggregate holidays:
for (var i = 0; i < data.length; i++) {
//console.log(data[i].holiday);
/*other stuff here*/
if (data[i].holiday.length > 0)
summary[data[i].holiday] = summary[data[i].holiday] + 1 || 1;
}
but this gives me invalid results, because in my data array holiday contains spaces.
I need a way to fix this and to split holidays based on dayType.
MY SOLUTION: My version of answer:
var summary = {}, d, tmp, type;
for (var i = 0; i < data.length; i++) {
var d = data[i];
if (d.holiday.length > 0) {
type = d.dayType == 'Weekend' || d.dayType == 'Free' ? 'Weekend' : 'Work';
tmp = summary[d.holiday];
if (!tmp) {
tmp = {
Weekend: 0,
Work: 0
};
summary[d.holiday] = tmp;
}
summary[d.holiday][type] += 1;
}
}
Because this is modified version of @Arun answer I'm not posting this as standalone answer.
I find my version easier to understand, hope someone find's it useful.
Upvotes: 0
Views: 1549
Reputation: 19098
Here's my attempt:
var summary = [];
var holidayTypes = [];
var dayTypes = [];
//first work out the different types of holidays
for (var i = 0; i < data.length; i++) {
if(holidayTypes.indexOf(data[i].holiday) == -1){
//this is a new type of holiday
holidayTypes.push(data[i].holiday);
}
if(dayTypes.indexOf(data[i].dayType) == -1){
//new type of day.
dayTypes.push(data[i].dayType);
}
}
console.log('types of holiday: ' + JSON.stringify(holidayTypes));
console.log('types of day: ' + JSON.stringify(dayTypes));
for(index in holidayTypes){
var typeobj = {};
//create an object for each type of holiday
typeobj[holidayTypes[index]] = {};
for(index2 in dayTypes){
//initialize a count for each type of day
typeobj[holidayTypes[index]][dayTypes[index2]] = 0;
//iterate through the data and count the occurrences where the day AND holiday match.
//if they do, iterate the value.
for (var j = 0; j < data.length; j++){
if((data[j].holiday == holidayTypes[index])
&& (data[j].dayType == dayTypes[index2])){
typeobj[holidayTypes[index]][dayTypes[index2]]++;
}
}
}
summary.push(typeobj);
}
console.log(JSON.stringify(summary));
Output:
[{"One type of holiday":{"Weekend":1,"Work":0}},{"Another type":{"Weekend":1,"Work":1}},{"":{"Weekend":0,"Work":1}}]
It works but is unlikely to be as efficient as the guys above!
Upvotes: 0
Reputation: 27845
go for
console.log(Object.keys(summary).length);
instead of
console.log(summary.length);
Because you can get the number of elements in a js object by using the length attribute.
note: using Object.keys may lead you to browser compatibility issues. As its supported form IE 9 and Firefox 4. See more info in this MDN article.
you can find more info and solutions for this problem in this answer.
see the updated fiddle.
Upvotes: 1
Reputation: 388316
Try
var summary = [], summaryMap = {}, d, map, m;
for (var i = 0; i < data.length; i++) {
var d = data[i];
map = summaryMap[d.holiday];
if(!map){
map = {
Work: 0,
Weekend: 0
};
m = {};
m[d.holiday] = map;
summary.push(m);
summaryMap[d.holiday] = map;
}
map[d.dayType] += 1;
}
console.log(summary);
console.log(JSON.stringify(summary));
Demo: Fiddle
Upvotes: 2