【问题标题】:Adding values of multiple arrays with javascript (or jquery)使用 javascript(或 jquery)添加多个数组的值
【发布时间】:2014-01-22 16:40:15
【问题描述】:

我有一个项目需要我添加多个数组的值,不一定都是相同的长度。

我有 8 个长度可变的数组:

p1 = [1,5,6,8,3,8,]
p2 = [3,3,3,2,8,3,3,4]
p3 = [1,2,3,4,5,6,7,8,9]
p4 = [1,3,4,5,6,7,2,0,2,8,7]

等等。

我需要做的是将相同的键值添加在一起以创建 1 个“结果”数组,如下所示:

结果 = [6, 13, 16, 19, 22, 24, 12, 12, 11, 8, 7]

我在 Stackoverflow 上找到了一些代码,它们在大多数浏览器中都能很好地完成这项工作,IE8 除外。

Javascript merge 2 arrays and sum same key values

这是适用于大多数浏览器的代码:

    var sums = {}; // will keep a map of number => sum
    [p1, p2, p3, p4, p5, p6, p7, p8].forEach(function(array) {
    //for each pair in that array
    array.forEach(function(pair) {
                    // increase the appropriate sum
                    sums[pair[0]] = pair[1] + (sums[pair[0]] || 0);
            });
    });



    // now transform the object sums back into an array of pairs, and put into array named 'results'...
    var results = [];
    for(var key in sums) {
            results.push([key, sums[key]]);
    }

问题(我认为)是 IE8 不支持 forEach。有没有办法在不使用 forEach 的情况下使用纯 Javascript 或 jQuery 来做到这一点?

【问题讨论】:

    标签: javascript jquery arrays internet-explorer-8


    【解决方案1】:

    您可以填充 forEach,而不是更改代码。

    这是来自 MDN 的代码,几乎是“官方”版本:

    if (!Array.prototype.forEach)
    {
      Array.prototype.forEach = function(fun /*, thisArg */)
      {
        "use strict";
    
        if (this === void 0 || this === null)
          throw new TypeError();
    
        var t = Object(this);
        var len = t.length >>> 0;
        if (typeof fun !== "function")
          throw new TypeError();
    
        var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
        for (var i = 0; i < len; i++)
        {
          if (i in t)
            fun.call(thisArg, t[i], i, t);
        }
      };
    }
    

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

    显然,您可以使用常规 for 而不是使用 forEach,但这意味着为了一个坏苹果而更改相当优雅的代码。

    【讨论】:

    • 感谢 Tibos 的回答,但作为 javascript/jquery 新手,我对您实际使用 shim 的方式有点迷茫?你能解释一下吗?
    • 只需将它放在对 forEach 的任何调用之前。该代码基本上检查是否已定义 forEach 以及是否未添加实现。从那时起,您可以使用 forEach 知道本机实现存在或 shim 存在。
    • 不得不自我救赎。 jsperf.com/adding-up-by-key-values。我更新了 JSFiddle 以尝试匹配您所拥有的。 jsfiddle.net/rSMxX/2
    • @Mark 是的,从性能的角度来看,在 forEach 中完成了更多操作,对于这种特定用途来说不需要,所以它更慢。令人印象深刻的是它慢了多少,但仍然如此。我喜欢遍历数组的函数式方法,因为如果不是瓶颈,额外的代码清晰度通常比性能提升更有价值。如果事实证明 forEach 是一个瓶颈,我会优化它,但不是之前。
    • 是的,我认为 [p1,p2,p3...].foreach 无法在 jsfiddle 上正常工作。我得到一个NaN。更新了 jsfiddle。 jsfiddle.net/rSMxX/3
    【解决方案2】:

    jquery 版本是:

    $.each(array,function(i,pair){ 
        ....
    });
    

    还有纯js:

    for (var i =0;i<array.length;i++){
      var pair = array[i];
      ....
    }
    

    或制作原创作品:

    if (!Array.prototype.forEach){
      Array.prototype.forEach = function(f){
        for (int i=0;i<this.length;i++){
          f(this[i]);
        }
      }
    }
    

    Array.prototype.forEach polyfill

    【讨论】:

      【解决方案3】:

      我只是直接切到你想要的结果。但从性能的角度来看,我会在一些循环上做一些 jsperf.com 测试,并测试浏览器如何处理数字并感受 $.each vs for vs while 循环和原型。

      function sumTotals(arr) {
          var sum = 0,
              len = arr.length,
              i = 0;
          while (i < len) {
              sum += arr[i] || 0;
              i += 1;
          }
          return sum;
      }
      while (i < len ) {
          sums.push(sumTotals(merged[i]));
          i += 1;
      }
      alert(sums);
      

      http://jsfiddle.net/rSMxX/

      更新了我的快速回答,以尝试匹配您显示的内容。但是根据我为您的 p1-8 数组使用的代码,您拥有的代码并没有飞行。我收到 TypeError 'undefined' is not an object(评估 forEach)。所以苹果对苹果,可能不得不解决这个问题。

      while (i < len ) {
          var j = 0,
              mlen = merged[i].length;
          while (j < mlen) {        
              sums[j] = (merged[i][j] || 0) + (sums[j] || 0);
              j += 1;
          }
          i += 1;
      }
      for(var key in sums) {
          //results.push([key, sums[key]]);
          results.push(sums[key]);
      }
      alert(results);
      

      http://jsperf.com/adding-up-by-key-valueshttp://jsfiddle.net/rSMxX/2/

      【讨论】:

      • 谢谢马克。我已经检查过了,它似乎将每个单独数组的键相加并将其放入一个数组中。我需要它分别对 8 个数组中的每一个(p1[0] + p2[0] + p3[0] 等)的键求和,并将结果放入一个数组中。抱歉,如果我解释得不够清楚。
      • 我的错,你说将键值加在一起,我吹过并添加了数组的总和。
      猜你喜欢
      • 2013-03-02
      • 1970-01-01
      • 1970-01-01
      • 2012-05-16
      • 2016-11-10
      • 1970-01-01
      • 2017-09-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多