[Chartjs]-Create New Array from Existing Array Values With Unique and Sum

2👍

Why not split into two arrays like you wanted?

function chartData(queryrowlist){
    // Set up our data store + return object
    var chart = {
        weeks: [],
        hours: []
    };
    // For every value in the parameter given
    angular.forEach(queryrowlist, function(value, key) {
        // Get the week, and check if it is in the array
        var week = moment(value.date).format('w');
        var weekIndex = chart.weeks.indexOf(week);

        // If the index is -1, it is not in the array, so just push values;
        if(weekIndex === -1) {
            chart.weeks.push(week);
            chart.hours.push([getOnHours(value),getOffHours(value)]);
        } else {

            // If the index is not, we assume that the weekIndex is the correct index to sum the values on.
            chart.hours[weekIndex] = [chart.hours[weekIndex][0] + getOnHours(value), chart.hours[weekIndex][1] + getOffHours(value)];
        }

    });
    return chart;
}

EDIT: New answer to reflect edit to question.

The algorithm will mostly stay the same, but the output array will change slightly.

function chartData(queryrowlist){
    // Set up our data store + return object
    var chart = {
        weeks: [],
        // Notice, two arrays in array
        hours: [
            [],
            []
        ]
    };
    // For every value in the parameter given
    angular.forEach(queryrowlist, function(value, key) {
        // Get the week, and check if it is in the array
        var week = moment(value.date).format('w');
        var weekIndex = chart.weeks.indexOf(week);

        // If the index is -1, it is not in the array, so just push values;
        if(weekIndex === -1) {
            chart.weeks.push(week);
            chart.hours[0].push(getOnHours(value));
            chart.hours[1].push(getOffHours(value));
        } else {

            // If the index is not, we assume that the weekIndex is the correct index to sum the values on.
            // Also notice the change to output to different arrays
            chart.hours[0][weekIndex] += getOnHours(value);
            chart.hours[1][weekIndex] += getOffHours(value);
        }

    });
    return chart;
}

1👍

You could use an object for grouping and later sort the keys and build the chart object with the sums.

var array = ["23", 28800000, 3600000, "23", 30300000, 2700000, "24", 35400000, 3300000, "24", 30000000, 3300000],
    chart = {},
    data = Object.create(null);

array.reduce(function (r, a, i) {
    if (i % 3 === 0) {
        if (!data[a]) {
            data[a] = { week: a, hours: [0, 0] };
        }
        return a;
    }
    data[r].hours[i % 3 - 1] += a;
    return r;
}, undefined);

Object.keys(data).sort(function (a, b) {
    return a - b;
}).forEach(function (k) {
    chart.weeks = chart.weeks || [];
    chart.hours = chart.hours || [];
    chart.weeks.push(data[k].week)
    chart.hours.push(data[k].hours);
});

console.log(chart);

0👍

If you didn’t need to maintain arrays for chart.js, I would use an object instead.

function chartData(queryrowlist){
  var weeks = {};
  angular.forEach(queryrowlist, function(value, key) 
  {
    var week = moment(value.date).format('w');
    if(!weeks[week]){ //new week
      weeks[week] = { 
        onHours: getOnHours(value),
        offHours: getOffHours(value)
      }
    } else { //week exists 
      weeks[week].onHours += getOnHours(value);
      weeks[week].offHours += getOffHours(value);    
    }
  });
  // create chart array ...
  return chart;
}

Result:
weeks = { 23: { onHours: 59100000 , offHours: 6300000 }, 24: { onHours: 65400000, offHours: 6600000 }}

And you would access it with weeks.week#.onHours or weeks[week#]['onHours'].

This will be much easier to read/follow/maintain than two separate arrays that need to be kept in sync.

Leave a comment