使用Unique和Sum从现有数组值创建新数组

时间:2016-06-21 16:52:13

标签: javascript arrays angularjs chart.js

出于某种原因,我绊倒了获得Javascript数组所需的结果。

我有包含日期​​的数据行,每行有几个时间戳。我需要做的是将数据转换为chart.js的数组,但是按周合并行,并将小时数(来自时间戳)相加。下面是我从查询结果创建一个新数组的地方,但我很难得到它我需要的方式。

我在这里创建数组(有处理):

function chartData(queryrowlist){
  var weeks = [];
  angular.forEach(queryrowlist, function(value, key) 
  {
    weeks.push(moment(value.date).format('w'),getOnHours(value),getOffHours(value))
  });
  // create chart array ...
  return chart;
}

周数组最终如下:

["23",28800000,3600000,"23",30300000,2700000,"24",35400000,3300000,"24",30000000,3300000]

周数,OnHours,OffHours

周数将用作标签,而小时数将用作角度图表/ chart.js中的开/关数据。问题是所有周数必须是唯一的,并且所有小时数都是每周总结的。

所以,我需要输出一个这样的数组:

chart['weeks']=["23","24"]
chart['hours']=[[59100000,6300000],[65400000,6300000]]

这可能很简单,只是我碰到了思考墙......但如果有人有解决方案,我会感激不尽。

提前谢谢。

更新:

对于任何可能引用此问题的人来说,结果数组对于chart.js是不正确的。下面的答案是正确的......正如我所问,我只是问了错误的事情而且只是在事后才意识到。感觉像个傻瓜:/

Chart.js想要同一个数组中的所有行值,所以代替上面的例子:

chart['weeks']=["23","24"]
chart['hours']=[[onhours,offhours],[onhours,offhours]]

应该是:

chart['weeks']=["23","24"]
chart['hours']=[[onhours,onhours],[offhours,offhours]]

更新2

进一步澄清:

对于每个标签,应该有一个值。如果您有3个标签,则应该有3个值。在我的情况下,有2组值数组,这是因为我有2个系列(2行),1个用于On Hours,1个用于Off Hours。所以这里是一个完整的数组列表。

chart['labels']=["23","24","25"] // strings
chart['data']=[[onhours,onhours,onhours],[offhours,offhours,offhours]] // integers
chart['series']=['On Hours','Off Hours'] // strings

如果我只需要1行:

chart['labels']=["23","24","25","26"] // strings
chart['data']=[[onhours,onhours,onhours,onhours]] // integers, notice [ [  ] ]
chart['series']=['On Hours'] // strings

希望有所帮助!

3 个答案:

答案 0 :(得分:2)

为什么不像你想要的那样分成两个数组?

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;
}

编辑:反映编辑问题的新答案。

算法大部分保持不变,但输出数组会略有变化。

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 :(得分:1)

您可以使用对象进行分组,然后对键进行排序,并使用总和构建图表对象。

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);

答案 2 :(得分:0)

如果你不需要为chart.js维护数组,我会使用一个对象。

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;
}

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

您可以使用weeks.week#.onHoursweeks[week#]['onHours']访问它。

这比两个需要保持同步的独立数组更容易阅读/跟踪/维护。