如果另一个数组具有相同的元素,则将数组元素连接起来

3

我有两个数组

var arrayA = ["a", "a", "b", "b", "a", "c"];
var arrayB = [10, 20, 3, 2, 20, 5];

如您所见,arrayA[0]、arrayA[1]、arrayA[4] 具有相同的元素(arrayA[2]、arrayA[3] 也是相同的)。
因此根据上面的例子,我希望 arrayB[0]、arrayB[1]、arrayB[4] 将被求和,arrayB[2]、arrayB[3] 也是如此。 期望输出
arrayA = ["a", "b", "c"];
arrayB = [50, 5, 5];

如果arrayA中的元素与其索引相同,则可以对arrayB元素进行求和吗?是否有Lodash/Underscore函数可以实现这一功能?


1
你尝试过什么吗? - Rajesh
4
可能是与从JS数组中删除重复值相关的重复问题。 - Pratansyah
2
@Pratansyah 虽然我非常感谢你的努力,但这并不是重复的。OP想要对第二个数组中的值进行求和,并使其唯一。 - Rajesh
8个回答

6

您可以使用对象作为索引并维护值。

var arrayA = ["a", "a", "b", "b", "a", "c"],
    arrayB = [10, 20, 3, 2, 20, 5],
    indices = Object.create(null),
    groupedA = [],
    groupedB = [];
    
arrayA.forEach(function (a, i) {
    if (!(a in indices)) {
        groupedA.push(a);
        indices[a] = groupedB.push(0) - 1;
    }
    groupedB[indices[a]] += arrayB[i];
});

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

变异原始数组的版本。

var arrayA = ["a", "a", "b", "b", "a", "c"],
    arrayB = [10, 20, 3, 2, 20, 5],
    indices = Object.create(null),
    i = 0;

while (i < arrayA.length) {
    if (!(arrayA[i] in indices)) {
        indices[arrayA[i]] = i++;
        continue;
    }
    arrayB[indices[arrayA[i]]] += arrayB.splice(i, 1)[0];
    arrayA.splice(i, 1);
}

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


哇...groupedB.push(0) - 1;,这真是一个非常好的方式 :) - Pranav C Balan
push 在推入元素后返回数组的长度。 - Nina Scholz
我对这个语句 indices[a] = groupedB.push(0) - 1; 有点困惑,能否再解释一下? - Engkus Kusnadi
@EngkusKusnadi,它在groupedB的末尾推送了值零,因为push返回数组的新长度,所以您可以通过减去1来获取最后插入项的索引。结果是哈希表indices中索引处的值为零。在下一行中,该索引用于更新哈希表相同项目索引处的总和。 - Nina Scholz

2

以下是使用lodash的解决方案:

[arrayA, arrayB] = _(arrayA)
    .zip(arrayB)
    .groupBy(0)
    .mapValues( grp => _.sumBy(grp,1))
    .thru(obj => [_.keys(obj), _.values(obj)])
    .value();

zip函数将arrayAarrayB中的每个元素一一对应,例如:[ ['a', 10], ['a', 20], ...]

然后,我们通过groupBy函数将位置0上的值进行分组,得到一个类似如下的对象:

{
   a: ['a', 10], ['a', 20], ['a', 20'],
   b: ['b', 3] ...,
   c: ...
}

每个键的值被映射到在位置1中的值的总和,最后将键和值分别返回为数组。

2
你可以将这两个数组转化为一个 ES6 的 Map,然后将 arrayA 的 keys 和 arrayB 的 values 展开:

你可以 将两个数组 转化为一个 ES6 的 Map,然后展开 arrayA 的 keys 和 arrayB 的 values

const arrayA = ["a", "a", "b", "b", "a", "c"];
const arrayB = [10, 20, 3, 2, 20, 5];

const map = arrayA.reduce((m, c, i) => m.set(c, (m.get(c) || 0) + arrayB[i]), new Map());

const arrA = [...map.keys()];
const arrB = [...map.values()];

console.log(arrA);

console.log(arrB);


1
使用一个中介的“result”对象:
var arrayA = ["a", "a", "b", "b", "a", "c"];
var arrayB = [10, 20, 3, 2, 20, 5];
var result = {};

for (var i = 0, max = arrayA.length; i < max; i++) {
    if (!result[arrayA[i]]) {
        result[arrayA[i]] = 0;
    }

    result[arrayA[i]] += arrayB[i];
}

var keys = Object.keys(result);

arrayA = [];
arrayB = [];
for (var i = 0, max = keys.length; i < max; i++) {
    arrayA.push(keys[i]);
    arrayB.push(result[keys[i]]);
}

1
let _ = require('underscore');

var arrayA = ["a", "a", "b", "b", "a", "c"];
var arrayB = [10, 20, 3, 2, 20, 5];

let res = {};
_.each(arrayA, (item, key) => {

  if (! res[item]) {
    res[item] = arrayB[key];
  } else {
    res[item] = res[item] + arrayB[key];
  }

});

arrayA = [];
arrayB = [];

_.each(res,(value,key) => {
  arrayA.push(key);
  arrayB.push(value);
});

console.log(arrayA);
console.log(arrayB);

1
首先填充字典,然后使用键和值填充数组。
let arrayA = ["a", "a", "b", "b", "a", "c"];
let arrayB = [10, 20, 3, 2, 20, 5];

let result = {};

for (let i=0; i < arrayA.length; i++ ){
    let valueB = 0;
    if (arrayB.length > i) {
        valueB = arrayB[i];
    }

    if (result.hasOwnProperty(arrayA[i])) {
      result[arrayA[i]] += valueB;
    }
    else {
      result[arrayA[i]] = valueB;
    }
}

let resultA = [];
let resultB = [];
for (let k in result) {
    resultA.push(k);
    resultB.push(result[k]);
}
console.log(resultA);
console.log(resultB);

1
使用Array#reduce方法。

var arrayA = ["a", "a", "b", "b", "a", "c"];
var arrayB = [10, 20, 3, 2, 20, 5];

// reference to keep the index
var ref = {},
  // array for keeping first result
  res1 = [];


var res2 = arrayA
  // iterate over the first array
  .reduce(function(arr, v, i) {
    // check index presenet in the refernece object
    if (!(v in ref)) {
      // if not then define the index and insert  0 in the array(defining the new index)
      arr[ref[v] = arr.length] = 0;
      // push value into the array( for unique value )
      res1.push(v);
    }
    // update the element at the index
    arr[ref[v]] += arrayB[i];
    // return the array reference
    return arr;
    // initialize initial value as an empty array to keep result
  }, [])

console.log(res1, res2);


数组A的输出是什么? - Engkus Kusnadi

1
你可以计算数组B中与数组A中每个元素对应的所有元素之和,将这些总和存储在一个对象中,并使用Object.values获取总和的数组。

var arrayA = ["a", "a", "b", "b", "a", "c"];
var arrayB = [10, 20, 3, 2, 20, 5];

var sum = {};

arrayA.forEach((l, index) => {
    sum[l] = (sum[l] || 0) + arrayB[index];
});

var res = Object.values(sum);

console.log(res);

使用array.prototype.reduce可以更简短的完成:

var arrayA = ["a", "a", "b", "b", "a", "c"];
var arrayB = [10, 20, 3, 2, 20, 5];

var res = Object.values(arrayA.reduce((m, l, index) => {
    m[l] = (m[l] || 0) + arrayB[index];
    return m;
}, {}));

console.log(res);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接