2015-10-19 55 views
0

我有具有相似的結構分組並添加JSON對象多鍵

data =[{"name":"A","Date":"10/19/2015","OnTime":"0.1","Purpose":"x","OffTime":"0"}, 
     {"name":"A","Date":"10/19/2015","OnTime":"0.3","Purpose":"x","OffTime":"0"}, 
     {"name":"B","Date":"10/19/2015","OnTime":"0.01","Purpose":"y","OffTime":"0"}, 
     {"name":"C","Date":"10/19/2015","OnTime":"0.02","Purpose":"z","OffTime":"0"}, 
     {"name":"C","Date":"10/19/2015","OnTime":"0.01","Purpose":"x","OffTime":"0"} 
     {"name":"A","Date":"10/20/2015","OnTime":"0.01","Purpose":"x","OffTime":"0"}] 

我想組和名稱和日期添加準時值這個JSON數據。例如在2015年10月19日的日期預期 O/P爲甲總龍泰值:

dataout = [{"name":"A","Date":"10/19/2015","OnTime":"0.4"}, 
      {"name":"A","Date":"10/20/2015","OnTime":"0.01"}, 
      {"name":"B","Date":"10/19/2015","OnTime":"0.01"}, 
      {"name":"C","Date":"10/19/2015","OnTime":"0.03"}] 

我嘗試使用搜索的解決方案,但發現對單個密鑰加法而不是多個密鑰的溶液。我也嘗試使用下劃線js,但無法獲得預期的輸出。請幫忙,謝謝。

+1

如果這個數據是從服務器檢索的,比如說使用SQL,那麼在那裏進行分組會更容易得多。 Javascript並不是真正爲這種事情設計的。它可以完成,但它是一個正確的faff。 – NickJ

+0

感謝您的幫助,但可悲的是我在這裏與javascript卡住了。我正在嘗試其他選項,希望這可以在JavaScript中完成。 – hitech0101

+0

@ hitech0101,請參閱下面的解決方案。 :-D –

回答

2

好吧,我有一些適合你的東西。

見小提琴這裏:

http://jsfiddle.net/chrislewispac/nw0bberb/1

//make new sorted array for future map loop which goes in order 
//using underscore.js you can chain methods. The sortBy method 
//allows chaining and by multiple attributes. First sort by name 
//then sort by date and return the value to new array 'sorted' 

var sorted = _.chain(data) 
    .sortBy(function(d) {return d.name}) 
    .sortBy(function(d) { return d.Date }) 
    .value() 

//declare vars for loop 
var prevObj = {}; 
var indexToChange = 0; 
var reformattedArray = []; 

//map loop over newly sorted array. I use map here which creates a new 
//array with the results of calling a provided function on every 
//element in this array. 

var reformattedArray = sorted.map(function (obj, index) { 

    //if the previous objects date is the same as the current objects 
    //date then take index of array which contains previous object 
    //which had same name and date properties and combine the OnTime 
    //values after converting them to float values using parseFloat() 

    if (prevObj.Date == obj.Date && prevObj.name == obj.name) { 
     reformattedArray[indexToChange].OnTime = parseFloat(prevObj.OnTime) + parseFloat(obj.OnTime); 
    } 

    //if they don't match then add current object to the end of 
    //the new array 

    else { 
     reformattedArray.push(obj); 
    } 

    //at the end of the loop assign the current object to value prevObj 
    //to be used in the next iteration 
    prevObj = obj; 

    //get current length of array (which is being built in our loop) 
    //and subtract one to get index of previous object 
    indexToChange = reformattedArray.length - 1; 

    //return the newly reformatted array 

    return reformattedArray; 

}); 

console.log(reformattedArray[0]); 

輸出是:

[ 
    {"name":"A","Date":"10/19/2015","OnTime":0.4,"Purpose":"x","OffTime":"0"}, 
{"name":"B","Date":"10/19/2015","OnTime":"0.01","Purpose":"y","OffTime":"0"}, 
{"name":"C","Date":"10/19/2015","OnTime":0.03,"Purpose":"z","OffTime":"0"}, 
{"name":"A","Date":"10/20/2015","OnTime":"0.01","Purpose":"x","OffTime":"0"} 
] 

參考文獻:

Underscore: sortBy() based on multiple attributes

http://underscorejs.org/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat

+0

「如果它工作」結合沒有解釋代碼,這段代碼在做什麼? -1 –

+0

@StephanBijzitter你是在開玩笑吧?它被評論,並有一個小提琴表明它的工作 –

+0

不,我不是在開玩笑。 –

-2

事情是這樣的,也許:

function GroupBy(array){ 
    var fields = Array.prototype.slice.call(arguments, 1); 
    var field = fields.shift(); 

    if(field){ 

    var groupedArray = []; 
    for(var i in array){ 
     var index = array[i][field]; 
     groupedArray[index] = groupedArray[index] || []; 
     groupedArray[index].push(array[i]); 
    } 

    for(var i in groupedArray) 
     groupedArray[i] = GroupBy.bind(null, groupedArray[i]).apply(null, fields); 

    return groupedArray; 
    } 

    return array; 
} 

沒有測試過,所以不要指望它的工作。但這應該是一個好的開始。

這是你如何使用它。

var array = [...]; //your array 
var groupedArray = GroupBy(array, "name", "Date"); 

//Then to get records by a specific fields just: 
var A_10192015 = groupedArray["A"]["10/19/2015"]; 
+0

請試試這個謝謝。 – hitech0101

+0

未經測試,「不期望它能工作」,沒有解釋代碼,這段代碼在做什麼? -1 –

+0

我試過這個,不能得到它的工作: - \ –

0

假設有沒有錯字,準時必須是數字,而不是示例中定義一個字符串,我們可以做這樣的:

  1. 通過所需的屬性進行分組,例如「日期」 &「」名稱」,在步驟給出1返回一個陣列,其中每個項目是至少1項的數組=>映射此結果,減少的值來總結
  2. 結果。

否則步驟1用GROUPBY,而不是一種避免你的代碼中的序列破裂,並允許您撥打減少。

var data = [{"name":"A","Date":"10/19/2015","OnTime":"0.1","Purpose":"x","OffTime":"0"}, 
 
    {"name":"A","Date":"10/19/2015","OnTime":"0.3","Purpose":"x","OffTime":"0"}, 
 
    {"name":"B","Date":"10/19/2015","OnTime":"0.01","Purpose":"y","OffTime":"0"}, 
 
    {"name":"C","Date":"10/19/2015","OnTime":"0.02","Purpose":"z","OffTime":"0"}, 
 
    {"name":"C","Date":"10/19/2015","OnTime":"0.01","Purpose":"x","OffTime":"0"}, 
 
    {"name":"A","Date":"10/20/2015","OnTime":"0.01","Purpose":"x","OffTime":"0"}]; 
 
console.log(_(data).chain() 
 
    .groupBy(function(itm){return itm.Date + itm.name;}) // group by date & name 
 
    .map(function(itm,key){ // for every grouped item 
 
    // we sum up the values OnTime 
 
    var sum=_(itm).chain() 
 
       .pluck("OnTime") 
 
       .reduce(function(memo, value){ 
 
        return memo =memo+ Number(value); 
 
       },0.0) 
 
       .value(); 
 
    return _.object(["name","Date", "OnTime"],[itm[0].name,itm[0].Date,sum])}) 
 
    .value() 
 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

是否足夠優雅?I H開啓!