【问题标题】:Javascript - sum 2d arrays [duplicate]Javascript - 对二维数组求和 [重复]
【发布时间】:2016-10-22 20:08:03
【问题描述】:

我有 2 个二维数组

var arr1 = [
  [1, 'a'],
  [2, 'b']
]

var arr2 = [
  [3, 'a'],
  [5, 'c']
]

我想将这两个数组相加得到这个结果

var output = [
  [4, 'a'],
  [2, 'b'],
  [5, 'c']
]

我尝试编写 2 个 .map 函数,但连同所需的结果,这将返回很多重复项:

function sumArrays (arr1, arr2) {
  var output = [];
  arr2.map(function(i) {
    arr1.map(function(n) {
      if (i[1] === n[1]) {
        output.push([i[0] + n[0], i[1]])
      } else {
        output.push(i)
      }
    })
  })
  return output;
}

有没有更简单的方法可以做到这一点,或者我现在应该删除除特定字符串的最高值之​​外的所有内容?

感谢您的帮助。

【问题讨论】:

  • 你想得到一个包含组合结果的新数组吗?
  • 我需要返回两个数组的总和。我可以通过修改现有的或返回一个新的来做到这一点。
  • 使用地图会更容易,如{a : 4, b : 2, c : 5}
  • arr1.concat(arr2).reduce((a,b)=>{return b[1] in a?a[b[1]]+=b[0]:a[b[1]]=b[0],a;},{});

标签: javascript arrays


【解决方案1】:

当您不需要新数组时,请不要使用Array#map,此方法会返回该数组。

您可以对清单使用哈希表,并检查 arr2 并将其更新为 Array#forEach

使用arr1 进行更新的提案

var arr1 = [[1, 'a'], [2, 'b']],
    arr2 = [[3, 'a'], [5, 'c']],
    inventory = Object.create(null);

arr1.forEach(function (a) {
    this[a[1]] = a;
}, inventory);

arr2.forEach(function (a) {
    if (!this[a[1]]) {
        this[a[1]] = [0, a[1]];
        arr1.push(this[a[1]]);
    }
    this[a[1]][0] += a[0];
}, inventory);

console.log(arr1);
.as-console-wrapper { max-height: 100% !important; top: 0; }

result 提出新数组的建议。

var arr1 = [[1, 'a'], [2, 'b']],
    arr2 = [[3, 'a'], [5, 'c']],
    inventory = Object.create(null),
    result = arr1.map(function (a) {
        return this[a[1]] = [a[0], a[1]];
    }, inventory);

arr2.forEach(function (a) {
    if (!this[a[1]]) {
        this[a[1]] = [0, a[1]];
        result.push(this[a[1]]);
    }
    this[a[1]][0] += a[0];
}, inventory);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 控制台的绝妙技巧
  • 很好的解释。但是,预期的结果是一个数组,那为什么不使用数组呢?
  • @PraneshRavi,结果是一个数组,哪里没看到数组?
  • 错字!为什么不使用 map()?
  • 你的意思是Map? ES6?
【解决方案2】:

这个问题与this one基本相同,我在其中建议了相同的ES6代码,使用哈希(Set)和一些变体代码,在此不再赘述:

function sumArrays(a, b) {
    return Array.from(
        b.reduce( (m, [v,k]) => m.set(k, (m.get(k) || 0) + v),
                   new Map(a.map ( ([v,k]) => [k,v] )) ), // swap pairs
        ([k,v]) => [v,k]) // swap back afterwards;
}

var arr1 = [
  [1, 'a'],
  [2, 'b']
]

var arr2 = [
  [3, 'a'],
  [5, 'c']
]

var result = sumArrays(arr1, arr2);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案3】:

    您也可以使用 forEach()findIndex() 执行此操作。

    var arr1 = [
      [1, 'a'],
      [2, 'b']
    ]
    
    var arr2 = [
      [3, 'a'],
      [5, 'c']
    ]
    
    function sumArrays(arr1, arr2) {
      var r = arr1.slice(0);
      arr2.forEach(function(e) {
        var i = arr1.findIndex(function(a) {
          return e[1] == a[1];
        })
        i != -1 ? r[i][0] += e[0] : r.push(e)
      })
      return r;
    }
    
    console.log(sumArrays(arr1, arr2))

    【讨论】:

      【解决方案4】:

      连接两个数组,这样你就有一个包含所有元组的数组。

      然后减少该元组数组,以便累积所有兼容的元组。

      arr1.concat(arr2).reduce(function r(accumulator, iterand) {
      
          // base case: no tuples in accumulator
          if (accumulator.length == 0) {
              // add current tuple to our empty accumulator.
              return [iterand];
          }
      
          // first tuple in accumulator is compatible with the currently-inspected tuple
          if (accumulator[0][1] == iterand[1]) {
              // increment the count in the compatible tuple that already exists in the accumulator
              return [[accumulator[0][0]+iterand[0], accumulator[0][1]]].concat(accumulator.slice(1));
          }
      
          // currently-inspected tuple is not compatible with first tuple in accumulator. leave first tuple in accumulator unchanged. run the inductive case upon the remaining tuples in the accumulator.
          return [accumulator[0]].concat(r(accumulator.slice(1), iterand));
      
      }, [])
      

      这是一个功能性解决方案,不会改变您现有的任何输入数据。

      【讨论】:

        猜你喜欢
        • 2013-04-10
        • 2013-01-08
        • 2016-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-30
        • 2013-01-27
        • 2020-08-05
        相关资源
        最近更新 更多