减少数组的数组(Javascript)

问题描述 投票:0回答:2

我有一个数组,即:

 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

javascript arrays reduce
2个回答
1
投票

您可以使用

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);


0
投票

如果序列中有相同的组,您可以检查最后一组并添加值。

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);

© www.soinside.com 2019 - 2024. All rights reserved.