我有一个数组,即:
const arrayDaddy = [[x, 1], [x, 1], [y, 2], [y, 2], [y, 2], [z, 3]]
我的最终目标是采用上述
arrayDaddy
,如果两个项目具有相同的值arrayDaddy[i][1]
,则通过在arrayDaddy[i][0]
中添加数字来对其进行变异。此外,我想在添加后丢弃具有重复 arrayDaddy[i][0]
值的嵌套数组。这个过程在 arrayDaddy
上的预期结果如下:
arrayDaddy = [[x, 2], [y, 6], [z, 3]]
我想知道是否有办法使用
Array.prototype.reduce();
来实现这一点。如果不是,实现这个目标的简单方法是什么?
注意:不确定这是否重要,但索引 0 中具有相同值的所有项目将共享索引 1 值。例如考虑 [z, 3]。任何添加的 [z, ] 项在索引 1 中也将有一个 3。
我确实尝试了
reduce();
但没有成功。我的代码看起来像这样:
const arrayDaddy = [[x, 1], [x, 1], [y, 2], [y, 2], [y, 2], [z, 3]] ;
arrayDaddy.reduce((arr1, arr2) => {
if(arr1[0] === arr2[0]){
arr1[1] += arr2[1]
// do something here to delete arr2... but I can't use delete on a local variable?
} else {
//do nothing, continue to the next arr in arrayDaddy
}
});
我也考虑过映射,但想避免创建一个新数组。我想变异
arrayDaddy
您可以使用
reduce
生成。首先,您必须通过作为子数组第一个元素的键来存储值。例如,使用Map
。因此,您将在 reduce 中更新 Map
,完成后将其转换为 Array
.
注意: 地图的元素通过创建它们的键来排序。
const arrayDaddy = [["x", 1], ["x", 1], ["y", 2], ["y", 2], ["y", 2], ["z", 3]];
const res = Array.from(arrayDaddy.reduce((p, c) => {
const prevVal = p.get(c[0]) || 0;
p.set(c[0], prevVal + c[1])
return p;
}, new Map()));
console.log(res);
没有地图
如果你真的不想使用 Map 你必须需要在对象中存储子数组的引用。
const arrayDaddy = [["x", 1], ["x", 1], ["y", 2], ["y", 2], ["y", 2], ["z", 3]];
// _tmp is to store the reference and _idx the current loop index
let _tmp = {};
let _idx = 0;
while (_idx < arrayDaddy.length) {
// Get current element
const element = arrayDaddy[_idx];
// If the item is not stored, must store and skip the element
if (_tmp[element[0]] === undefined) {
_tmp[element[0]] = element;
++_idx;
continue;
}
// Update value and drop array element
_tmp[element[0]][1] += element[1];
arrayDaddy.splice(_idx, 1);
}
console.log(arrayDaddy);
无店铺参考值
如果您不想存储任何引用以节省内存,则必须迭代每个元素并检查索引是否有一个 previus 以便能够对当前值求和并删除当前元素。
const arrayDaddy = [["x", 1], ["x", 1], ["y", 2], ["y", 2], ["y", 2], ["z", 3]];
// _idx is one because you don't need process the 0 element
let _idx = 1;
while (_idx < arrayDaddy.length) {
// Get current element
const element = arrayDaddy[_idx];
// Check if has previous element
let prevFind = false;
for (let pi = _idx - 1; pi >= 0; --pi) {
// If find, update value, drop array element and set prevFind flag
if (arrayDaddy[pi][0] === element[0]) {
arrayDaddy[pi][1] += element[1];
arrayDaddy.splice(_idx, 1);
prevFind = true;
break;
}
}
// No previuos value, go next
if (!prevFind) {
++_idx;
}
}
console.log(arrayDaddy);
如果序列中有相同的组,您可以检查最后一组并添加值。
const
[x, y, z] = 'xyz';
array = [[x, 1], [x, 1], [y, 2], [y, 2], [y, 2], [z, 3]],
result = array.reduce((r, [k, v]) => {
if (r.at(-1)?.[0] === k) r.at(-1)[1] += v;
else r.push([k, v]);
return r;
}, []);
console.log(result);