2014-05-14 52 views
0

我有一些JSON數據需要分割然後聚合。這是一個格式樣本。劃分和彙總json數據

data2 = [{"startDate": 1396263600.0, "adId": 2483231759355, "endDate": 1401101940.0,  "impressions": 754831}, 
{"startDate": 1393851600.0, "adId": 2750329551133, "endDate": 1404212340.0, "impressions": 3947368}, 
{"startDate": 1401620400.0, "adId": 1311595275159, "endDate": 1404212340.0, "impressions": 630000}]; 

我想統一劃分日期範圍內每天的展示次數。 (即如果在10天的範圍內有100次展示,那麼每天將獲得10次展示)。然後,我想彙總每天所有廣告的展示次數(例如,如果某天有兩個廣告,則它們合併)。所以最終的結果將是一連串的日子和印象。不太熟悉JavaScript,所以不確定是否有任何功能讓我的生活更輕鬆。有什麼建議麼?

我打算使用這個函數來計算日期之間的天數:

function days_between(date1, date2) { 

    // The number of milliseconds in one day 
    var ONE_DAY = 1000 * 60 * 60 * 24; 

    // Convert both dates to milliseconds 
    var date1_ms = date1 * 1000; 
    var date2_ms = date2 * 1000; 

    // Calculate the difference in milliseconds 
    var difference_ms = Math.abs(date1_ms - date2_ms); 

    // Convert back to days and return 
    return Math.round(difference_ms/ONE_DAY); 

} 

回答

0

所以這樣的事情?這會將每天的展示次數獲取到javascript對象中,每個日期以毫秒爲關鍵字(例如1403953200000:21000)。您可以在毫秒轉換成一個日期,如果你想要的,21000是在那一天

var result={}; 

for(var i=0;i<data2.length;i++){ 
    var end = new Date(data2[i].endDate*1000); 
    var start = new Date(data2[i].startDate*1000); 
    var diff= Math.abs(end.getTime() - start.getTime()); 
    var diffDays = Math.ceil(diff/(1000 * 3600 * 24)); 

    for (; start <= end; start.setDate(start.getDate() + 1)) { 
     var miliseconds=start.getTime(); 
     if(!result.hasOwnProperty(miliseconds)) result[miliseconds]=0; 
     result[miliseconds]+=data2[i].impressions/diffDays; 
    } 

} 

console.log(result) 

更新的印象:

function aggregate(data2) { 
    var result={}; 
    var result_arr=[];  
    for(var i=0;i<data2.length;i++){ 
     var end = new Date(data2[i].endDate*1000); 
     end.setHours(0); 
     end.setMinutes(0); 
     end.setSeconds(0); 
     var start = new Date(data2[i].startDate*1000); 
     start.setHours(0); 
     start.setMinutes(0); 
     start.setSeconds(0);   
     var diff= Math.abs(end.getTime() - start.getTime()); 
     var diffDays = Math.ceil(diff/(1000 * 3600 * 24)); 
     console.log(start.toString(),end.toString(), diffDays) 
     for (; start <= end; start.setDate(start.getDate() + 1)) { 
      var miliseconds=start.getTime(); 
      if(!result.hasOwnProperty(miliseconds)) result[miliseconds]=0; 
      result[miliseconds]+=data2[i].impressions/diffDays; 
     } 
    } 

    for(var key in result){ 
     result_arr.push({date:Number(key), impressions: result[key]}); 
    } 
    result_arr.sort(function(a,b){return a.date > b.date}) 
    return result_arr; 
} 

撥弄我的工作的解決方案:http://jsfiddle.net/juvian/6R7mu/14/

+0

希望保持最終結果有相同的格式輸入只是2場(日期和次數),而不是4. – user40721

+0

@ user40721根據我在Grainier的主題中的評論檢查我的更新答案 – juvian

+0

- 結果似乎沒有意義。由於有2個日期範圍,所以應該只有1個峯值。 請參閱http://jsfiddle.net/hohenheim/6R7mu/24/,瞭解使用linq.js和完整數據集的正確解決方案。 – user40721

1

是你在想這樣的事情嗎?

function days_between(date1, date2) { 
    var date1_ms = new Date(date1*1000).getTime(); 
    var date2_ms = new Date(date2*1000).getTime(); 

    // Calculate the difference in milliseconds 
    var difference_ms = Math.abs(date1_ms - date2_ms); 

    // Convert back to days and return 
    return Math.ceil(difference_ms/(1000 * 3600 * 24)); 
} 


function aggregate(data) { 
    result = []; 
    for (var i = 0; i < data.length; i++) { 
     var numOfDays = days_between(data[i].startDate, data[i].endDate); 
     var adId = data[i].adId; 
     var impressionPerDay = (data[i].impressions/numOfDays); 
     for (var j = 0; j < numOfDays; j++) { 
      var obj = {}; 
      obj.date = new Date(new Date(data[i].startDate*1000).getTime() + (j * (1000 * 3600 * 24))).getTime(); 
      obj.impressions = impressionPerDay; 
      obj.adId = adId; 
      result.push(obj); 
     } 
    } 
    return result; 
} 

function aggregateAdIds(data) { 
    var result = {}; 
    for (var i = 0; i < data.length; i++) { 
     if (data[i].adId in result) result[data[i].adId].push({"date": data[i].date, "impressions": data[i].impressions}); 
     else result[data[i].adId] = [{"date": data[i].date, "impressions": data[i].impressions}]; 
    } 
    return result; 
} 

var data = [{"startDate": 1396263600.0, "adId": 2483231759355, "endDate": 1401101940.0,  "impressions": 754831},{"startDate": 1393851600.0, "adId": 2750329551133, "endDate": 1404212340.0, "impressions": 3947368},{"startDate": 1401620400.0, "adId": 1311595275159, "endDate": 1404212340.0, "impressions": 630000}]; 


var final = aggregateAdIds(aggregate(data)); 

修訂

function days_between(date1, date2) { 
    var date1_ms = new Date(date1*1000).getTime(); 
    var date2_ms = new Date(date2*1000).getTime(); 

    // Calculate the difference in milliseconds 
    var difference_ms = Math.abs(date1_ms - date2_ms); 

    // Convert back to days and return 
    return Math.ceil(difference_ms/(1000 * 3600 * 24)); 
} 


function aggregate(data) { 
    var map = {}; 
    var result = []; 
    for (var i = 0; i < data.length; i++) { 
     var numOfDays = days_between(data[i].startDate, data[i].endDate); 
     console.log('days : '+ numOfDays); 
     var impressionPerDay = (data[i].impressions/numOfDays); 
     for (var j = 0; j < numOfDays; j++) { 
      var tempDate = new Date(data[i].startDate*1000); 
      tempDate.setDate(tempDate.getDate() + j); 
      var date = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate(), 0, 0 ,0, 0); 
      if (date.getTime() in map) map[date.getTime()] += impressionPerDay; 
      else map[date.getTime()] = impressionPerDay; 
     } 
    } 
    for (var key in map) { 
     result.push({'date' : Number(key), 'impressions' : map[key]}); 
    } 
    result.sort(function(a,b){return a.date > b.date}); 
    return result; 
} 

var data = [{"startDate": 1396263600.0, "adId": 2483231759355, "endDate": 1401101940.0,  "impressions": 754831},{"startDate": 1393851600.0, "adId": 2750329551133, "endDate": 1404212340.0, "impressions": 3947368},{"startDate": 1401620400.0, "adId": 1311595275159, "endDate": 1404212340.0, "impressions": 630000}]; 


console.log(aggregate(data)); 

更新小提琴:link

+0

這是第一部分,但我也需要在adIds上進行彙總。 最終結果應該只有日期和印象。 – user40721

+0

我編輯了答案,這是你想要的嗎? – Grainier

+0

這看起來不太正確 - 您的結果是以{}開始 - 但不應該是[]? 讓我更具體: 假設我們有(在運行你的聚合函數後): [{「date」:100,「adId」:1,「impressions」:10},{「date」:100 ,「adId」:1,「展示次數」:30},{「日期」:200,「adId」:1,「展示次數」:20}]; 那麼最終輸出應該是: [{「date」:100,「impressions」:30},{「date」:200,「impressions」:20}]; – user40721