以下のように、JSの配列内に3つのオブジェクトがあります
[{"2013-03-02T00:00": 300}, {"2013-03-01T00:00": 200},{"2013-03-02T00:00": 50}]
上記の配列からの出力として、以下のようなものが必要です。
[{"2013-03-02T00:00": 350} , {"2013-03-01T00:00": 200}]
ループして追加することで実行できますが、効率的な方法はありますか?
前もって感謝します。
以下のように、JSの配列内に3つのオブジェクトがあります
[{"2013-03-02T00:00": 300}, {"2013-03-01T00:00": 200},{"2013-03-02T00:00": 50}]
上記の配列からの出力として、以下のようなものが必要です。
[{"2013-03-02T00:00": 350} , {"2013-03-01T00:00": 200}]
ループして追加することで実行できますが、効率的な方法はありますか?
前もって感謝します。
キー「日付」をオブジェクトの別の値として追加して、並べ替えおよびグループ化できる場合、配列にさらに多くの値がある場合、これはより迅速かつ最適化されます。
【追記】ちょっとしたバグを修正しました。
var arr = [{"date":"2013-03-02T00:00",val: 300}
, {"date":"2013-03-01T00:00",val: 200}
,{"date":"2013-03-02T00:00",val: 50}];
function groupArray(arr){
if(arr.length===0){return [];}
var pref,i;
// sort by date
arr.sort(function(a,b){
return (a.date>b.date)?1:(a.date<b.date)?-1:0;
});
// loop through the array grouping objects by date
pref=arr[0].date;
for(i=1;i<arr.length;i++){
if(arr[i].date===pref){
//set the total
arr[i-1].val=arr[i-1].val+arr[i].val;
//remove the element
arr.splice(i,1);
// set i one back
i--;
}
pref=arr[i].date;
}
return arr;
}
console.log(groupArray(arr));
より複雑な例は、ソートするキーを動的に提供したい場合です。上記の例では、キーは日付になるように「ハードコード」されていますが、別のキー値でグループ化する必要がある場合があります。次のコードは1つのキーでグループ化するように単純化したことを横に置いていました(元はキーの配列を使用していました)。2 つのアイテムをマージする方法を処理する関数である onMerge 変数を渡すことができます。この関数は一般的なものではなく、マージされるオブジェクトの val プロパティの追加に固有のものです。
var arr = [{"date":"2013-03-02T00:00",val: 300}
, {"date":"2013-03-01T00:00",val: 200}
, {"date":"2013-03-01T00:00",val: 200}
, {"date":"2013-03-01T00:00",val: 200}
, {"date":"2013-03-01T00:00",val: 200}
,{"date":"2013-03-02T00:00",val: 50}];
/**
* @param arr is the array to be merged
* @param key is the key to use for merge
* (like date) will merge on items with same
* date value
* @param onMerge function to call when 2 items
* are merged with the 2 items as parameters
**/
function groupArray(arr,key,onMerge){
if(arr.length===0){return [];}
var pref,i;
// sort by key
arr.sort(function(a,b){
return (a[key]>b[key])?1:(a[key]<b[key])?-1:0;
});
// loop through the array grouping objects by key
pref=arr[0][key];
for(i=1;i<arr.length;i++){
if(arr[i][key]===pref){
//merge 2 items, call the onMerge callback
arr[i-1]=onMerge(arr[i-1],arr[i]);
//remove the element
arr.splice(i,1);
// set i one back
i--;
}
pref=arr[i][key];
}
return arr;
}
// functon that will be called when 2 items are merged
// stay will stay and gone will be gone
// this function is specific to your data type
function onMergeCallback(stay,gone){
stay.val=stay.val+gone.val;
return stay;
}
console.log(groupArray(arr,"date",onMergeCallback));
データを操作および処理するための便利で効率的な関数が多数実装されているunderscore.jsを参照してください。具体的には、次の_.groupBy
関数を確認する必要があります。
var data = [{"2013-03-02T00:00": 300}, {"2013-03-01T00:00": 200},{"2013-03-02T00:00": 50}]
_.groupBy(data, function(obj) { return Object.keys(obj)[0]; })
反復して値を合計する必要がありますが、reduce 関数があるのはそのためです。
ユースケースにより具体的なものが必要な場合は、github のソースを参照してください。