什么是基于第n个元素合并数组的有效方法?

时间:2018-01-16 00:30:50

标签: javascript arrays algorithm optimization

这是相对简单的,但是我无法找到更优雅的解决方案。

假设您有一组n维数组,并且您想通过某种方法将具有匹配的mth元素的数组压缩在一起,让我们说加法。

示例:[[1, 100], [1, 200], [2, 100], [2, 105], [3, 202], [4, 133]]

结果: [[1, 300], [2, 205], [3, 202], [4, 133]]

我想出的解决方案对我来说似乎非常不优雅。有没有办法用更少的代码或更有效的方式来做到这一点?



function mergePairs(originalArray) {
  const newArray = [];
  originalArray.forEach((pair) => {
    const foundPair = newArray.find((newPair) => {
      return newPair[0] === pair[0];
    });
    if (foundPair) {
      foundPair[1] += pair[1];
    } else {
      newArray.push(pair);
    }
  });
  return newArray;
}




除此之外:如果在lodash中有一个厚颜无耻的单行程以超低效的方式完成同样的事情,我也很满意。

3 个答案:

答案 0 :(得分:1)

您可以针对特定情况使用reducemap

function mergePairs (originalArray) {
  const o = originalArray.reduce((a, e) => (a[e[0]] = ~~a[e[0]] + e[1]) && a, {});
  return Object.keys(o).map(k => [+k, o[k]]);
}

console.log(mergePairs ([[1, 100], [1, 200], [2, 100], [2, 105], [3, 202], [4, 133]]))

答案 1 :(得分:0)

如果您只是对数字进行排序,并且您希望数组已按升序排序(如您的示例):

function mergePairs(arr) {
  return arr.sort((a, b) => {
    if (a[0] === b[0]){
      a[1] += b[1];
      b[0] = 'del'
    }
  }).filter(val => val[0] !== 'del');
}

或者您可以将其分类为安全:

function mergePairs(arr) {
  arr.sort((a, b) => a[0] === b[0]);
  return arr.sort((a, b) => {
    if (a[0] === b[0]){
      a[1] += b[1];
      b[0] = 'del'
    }
  }).filter(val => val[0] !== 'del');
}

答案 2 :(得分:0)

就我个人而言,我发现拆分对然后重新组合会更有意义。我使用indexOf匹配数组,因为它比整个原始数组列表更有效。每次我遇到一个新值时,我都会将它添加到匹配列表中。匹配值可以是任何值,而不仅仅是数字,并且不必避免任何关键字。 〜将未找到的-1转换为0,这是假的。

function combine (complexArray){
    var matches = [];
    var totals = [];

    complexArray.forEach(simplify);

    function simplify(item) {
        var match = matches.indexOf(item[0]);
        if(~match) {
            totals[match] += item[1];
        } else {
            matches.push(item[0]);
            totals.push(item[1]);
        }
    }

    return matches.map(function(value, index) {
        return [value, totals[index]];
    });
}