2016-06-21 48 views
1

由于某种原因,我磕磕绊绊来得到我需要的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个用于开放时间,1个用于关闭时间。所以这里有一个完整的数组列表。

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 

希望帮助!

+0

你能在例如扩大?例如如果你有'chart ['weeks'] = [“23”,“24”,“25”]',你是否也应该有'chart ['hours'] = [[onhours,onhours,onhours],[offhours ,offhours,offhours]'? –

+0

@HopefulLlama - 是的,这是正确的。我已经更新了这些例子。希望现在更清楚。 – Chris

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

当同一周的数字出现多次时,他们想要进行求和操作。 – 4castle

+0

@ 4castle谢谢,我不知道为什么我没有注意到这一点。编辑我的答案,希望能够反映出来。 –

+0

你可以用'chart.hours [weekIndex] [0] + = getOnHours(value); chart.hours [weekIndex] [1] + = getOffHours(value);'。还记得'hours.push'应该推动一个数组,所以'hours.push([getOnHours(value),getOffHours(value)]);' – 4castle

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']访问它。

这比读取/遵循/维护要比两个需要保持同步的独立数组容易得多。

+0

他们正在将其导出到chart.js API,因此他们无法修改输出格式。我的评论是误导性的,所以我删除了它。 – 4castle

+0

感谢您的贡献。 – Chris

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

+0

这甚至可能是'reduce'在这里更有意义,因为它最终会进行简化操作以便对值进行求和。它可以使阅读更容易。 – 4castle

+0

在这里不起作用,因为我会失去'this.last' –

+1

难道你不能给reduce对象一个'last'字段吗? – 4castle