2013-10-07 55 views
6

的阵列相同的对象propertyB值一个人怎么会采取对象的JavaScript数组如:总和JavaScript对象propertyA与对象

my objArr = [ 
{key:Mon Sep 23 2013 00:00:00 GMT-0400, val:42}, 
{key:Mon Sep 24 2013 00:00:00 GMT-0400, val:78}, 
{key:Mon Sep 25 2013 00:00:00 GMT-0400, val:23}, 
{key:Mon Sep 23 2013 00:00:00 GMT-0400, val:54}] 

和值相加合并重复键。 为了得到这样的:

my reducedObjArr = [ 
{key:Mon Sep 23 2013 00:00:00 GMT-0400, val:96}, 
{key:Mon Sep 24 2013 00:00:00 GMT-0400, val:78}, 
{key:Mon Sep 25 2013 00:00:00 GMT-0400, val:23}] 

我曾尝试迭代,并添加到一个新的数组,但这并没有工作:

var reducedObjArr = []; 
var item = null, key = null; 
for(var i=0; i<objArr.length; i++) { 
    item=objArr[i]; 
    key = Object.keys(item)[0]; 
    item=item[key]; 

    if(!result[key]){ 
     result[key] = item; 
    }else{ 
     result[key] += item;} 
    }a 
+0

为什么你在做'键= Object.keys(项目)[0]; item = item [key];'?你已经知道这个名字是'key',所以只需要'item.key'或'objArr [i] .key'。另外,使用'[0]'索引不一定总会给你相同的属性。 – user2736012

回答

8

你应该将未找到的每个对象都分配给.key属性。

如果找到了,那么您需要添加它的.val

var temp = {}; 
var obj = null; 
for(var i=0; i < objArr.length; i++) { 
    obj=objArr[i]; 

    if(!temp[obj.key]) { 
     temp[obj.key] = obj; 
    } else { 
     temp[obj.key].val += obj.val; 
    } 
} 
var result = []; 
for (var prop in temp) 
    result.push(temp[prop]); 

此外,部分问题是,你被重用item变量引用的.key值,让你失去了参照对象。

3
var targetObj = {}; 
for (var i = 0; i < objArr.length; i++) { 
    if (!targetObj.hasOwnProperty(objArr[i].key)) { 
     targetObj[objArr[i].key] = 0; 
    } 
    targetObj[objArr[i].key] += objArr[i].val; 
} 

http://jsfiddle.net/HUMxp/

+0

OP需要相同的键/值对,但是要合并“val”。 – user2736012

0

以下是您的替代方案,但与Explosion Pills相似,重新使用原始数组而不是创建新的或不同的对象。这种排序可能不是必要的,会稍微放慢一些,但可以将其删除。

的Javascript

function reduceMyObjArr(arr) { 
    var temp = {}, 
     index; 

    for (index = arr.length - 1; index >= 0; index -= 1) { 
     key = arr[index].key; 
     if (temp.hasOwnProperty(key)) { 
      arr[temp[key]].val += arr[index].val; 
      arr.splice(index, 1); 
     } else { 
      temp[key] = index; 
     } 
    } 

    arr.sort(function (a, b) { 
     if (a.key === b.key) { 
      return 0; 
     } 

     if (a.key < b.key) { 
      return -1; 
     } 

     return 1; 
    }); 

    return arr; 
} 

var myObjArr = [{ 
    key: "Mon Sep 23 2013 00: 00: 00 GMT - 0400", 
    val: 42 
}, { 
    key: "Mon Sep 24 2013 00: 00: 00 GMT - 0400", 
    val: 78 
}, { 
    key: "Mon Sep 25 2013 00: 00: 00 GMT - 0400", 
    val: 23 
}, { 
    key: "Mon Sep 23 2013 00: 00: 00 GMT - 0400", 
    val: 54 
}]; 

reduceMyObjArr(myObjArr); 

console.log(myObjArr); 

jsFiddle

而一个jsperf就是比较这个(与不排序)对接受的答案。您可以通过扩展数据集来改进性能测试。

4

而不是使用一个for循环,推动值,你可以直接使用mapreduce

let objArr = [ 
 
    {key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 42}, 
 
    {key: 'Mon Sep 24 2013 00:00:00 GMT-0400', val: 78}, 
 
    {key: 'Mon Sep 25 2013 00:00:00 GMT-0400', val: 23}, 
 
    {key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 54} 
 
]; 
 

 
// first, convert data into a Map with reduce 
 
let counts = objArr.reduce((prev, curr) => { 
 
    let count = prev.get(curr.key) || 0; 
 
    prev.set(curr.key, curr.val + count); 
 
    return prev; 
 
}, new Map()); 
 

 
// then, map your counts object back to an array 
 
let reducedObjArr = [...counts].map(([key, value]) => { 
 
    return {key, value} 
 
}) 
 

 
console.log(reducedObjArr);

0

你也可以使用JavaScript LINQ框架,该框架为SQL语句完全相同尝试这是给予期望的输出与较少的书面代码和有效,并在linq.js发现

var objArr = 
 
[ 
 
{key:'Mon Sep 23 2013 00:00:00 GMT-0400', val:42}, 
 
{key:'Mon Sep 24 2013 00:00:00 GMT-0400', val:78}, 
 
{key:'Mon Sep 25 2013 00:00:00 GMT-0400', val:23}, 
 
{key:'Mon Sep 23 2013 00:00:00 GMT-0400', val:54} 
 
]; 
 

 

 
var aggregatedObject = Enumerable.From(objArr) 
 
     .GroupBy("$.key", null, 
 
       function (key, g) { 
 
        return { 
 
         key: key, 
 
         contributions: g.Sum("$.val") 
 
        } 
 
     }) 
 
     .ToArray(); 
 

 
console.log(aggregatedObject);
<script src="http://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.min.js"></script>

这与循环相比很容易。 我希望这可能有所帮助。

3

您可以使用散列表进行key的分组。

var array = [{ key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 42 }, { key: 'Mon Sep 24 2013 00:00:00 GMT-0400', val: 78 }, { key: 'Mon Sep 25 2013 00:00:00 GMT-0400', val: 23 }, { key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 54}], 
 
    grouped = []; 
 

 
array.forEach(function (o) { 
 
    if (!this[o.key]) { 
 
     this[o.key] = { key: o.key, val: 0 }; 
 
     grouped.push(this[o.key]); 
 
    } 
 
    this[o.key].val += o.val; 
 
}, Object.create(null)); 
 

 
console.log(grouped);