【问题标题】:Javascript object sum value based on properties effeicently有效地基于属性的 Javascript 对象总和值
【发布时间】:2013-05-16 09:16:09
【问题描述】:

我在 JS 的数组中确实有三个对象,如下所示

[{"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}]

可以通过循环和添加来完成,有什么有效的方法可以做到吗?

提前致谢。

【问题讨论】:

  • 你在这里面加了什么?您能否更新您的问题,使其更具描述性?
  • 啊。我知道了。你的问题有点不清楚,但你基本上想添加所有类似的键。
  • 您还能将数组更改为包含以下内容的项目:{'date':"2013-03-02T00:00",value:300} 这将更容易对项目进行分组和添加值因为您可以按日期对数组进行排序并一举获得相同的值。
  • 嗯,你可以使用 Array.map()..
  • @DavidZiemann 只是一点点?

标签: javascript arrays performance object


【解决方案1】:
var myList = [{"2013-03-02T00:00": 300}, {"2013-03-01T00:00": 200},{"2013-03-02T00:00": 50}];
var result = {};
var item = null, key = null;
for(c=0; c<myList.length; c++) {
   item=myList[c];
   key = Object.keys(item)[0];
   item=item[key];

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

console.log(result);

我将其作为练习留给读者,以将结果放入请求的表格中。 (毕竟你应该自己解决至少部分问题:)

【讨论】:

  • 您的 var c 在 for 循环中未定义,无法编辑,因为需要编辑的字符最少
【解决方案2】:

您可能想看看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 上的源代码。

https://github.com/documentcloud/underscore

【讨论】:

    【解决方案3】:

    如果您可以将键“日期”添加为对象的另一个值,您可以对其进行排序和分组,当数组中有更多值时,这将更快、更优化。

    [更新]:修复了一个小错误。

    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));
    

    一个更复杂的例子是当你动态地想要提供排序的键时,在上面的例子中,键被“硬编码”为日期,但你可能需要对另一个键值进行分组,下面是一段我放置的代码已简化为按一个键分组(最初使用的是一组键)。您可以传递一个 onMerge 变量,该变量应该是一个处理如何合并 2 个项目的函数。此函数不是通用的,专门用于添加要合并对象的 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));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-25
      • 1970-01-01
      • 2011-02-25
      相关资源
      最近更新 更多