2016-06-21 46 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