简体   繁体   English

合并 arrays,为什么我的输入数组发生了变异?

[英]Merging arrays, why is my input array mutated?

Here is what I'm trying to do:这是我正在尝试做的事情:

I have these 2 arrays as inputs.我有这 2 个 arrays 作为输入。 I want to combine them, and merge the objects that have the same "type" property and for these, add the quantities.我想组合它们,并合并具有相同“类型”属性的对象,并为这些对象添加数量。 So, with these 2 arrays below, I have an object with a "type" equal to veggie in each array.因此,有了下面的这 2 个 arrays,我有一个 object,每个数组中的“类型”等于 veggie。 The resulting array would have an object with a "type" veggie, and the associated quantity equal to 30 (27+3).生成的数组将具有 object 和“类型”蔬菜,相关数量等于 30 (27+3)。

const arr1 = [{"quantity": 27, "type": "veggie"}, {"quantity": 191, "type": "meat"}, {"quantity": 3, "type": "fruit"}];

const arr2 = [{"quantity": 13, "type": "fish"}, {"quantity": 191, "type": "dairy"}, {"quantity": 3, "type": "veggie"}];

const all = [...arr1, ...arr2];

function mergeArrays(arr) {
  const res = arr.reduce(function(acc, curr) {
    const findTagIndex = acc.findIndex((item) => item.type === curr.type);
    if (findTagIndex === -1) {
      acc.push(curr)
    } else {
      acc[findTagIndex].quantity += curr.quantity
    }
    return acc;
    }, []);

    return res;
}

const newArray = mergeArrays(all);

console.log(newArray) // [{quantity: 191, type: "meat"}, {quantity: 30, type: "veggie"}, {quantity: 3, type: "fruit"}, {quantity: 13, type: "fish"}, {quantity: 191, type: "dairy"}];

What I don't understand, and I'm stuck with, is that the merging of arrays seems to mutate arr1 .我不明白,我坚持的是, arrays 的合并似乎改变了arr1 If I console log of arr1 before and after getting the newArray , it will log resp.如果我在获取newArray之前和之后控制台arr1的日志,它将分别记录。 27 and 30 veggies. 27 和 30 种蔬菜。 What's going on?这是怎么回事?

Any suggestion what I am doing wrong?任何建议我做错了什么? How else can I proceed?我还能如何进行? I tried several things.我尝试了几件事。 I tried with a forEach .我尝试使用forEach Same result.结果相同。

You push the objects from the first array into the other array, thus both arrays hold references to the same objects.您将对象从第一个数组推送到另一个数组,因此 arrays 都持有对相同对象的引用 You can easily (shallow) copy the objects when pushing:推送时可以轻松(浅)复制对象:

 acc.push({ ...curr });

Here's how I'd do that (in O(n)):这是我的做法(在 O(n) 中):

 const quantityByType = new Map();

 for(const { type, quantity } of [...arr1, ...arr2]) {
   amountByType.set(type, quantity + (quantityByType.get(type) || 0));
 }

 const result = [...quantityByType.entries()]
      .map(([type, quantity]) => ({ type, quantity }));

It is possible to use reduce method to calculate sum:可以使用reduce方法来计算总和:

 const arr1 = [{"quantity": 27, "type": "veggie"}, {"quantity": 191, "type": "meat"}, {"quantity": 3, "type": "fruit"}]; const arr2 = [{"quantity": 13, "type": "fish"}, {"quantity": 191, "type": "dairy"}, {"quantity": 3, "type": "veggie"}]; const merged = arr1.concat(arr2); const result = merged.reduce((a, {type, quantity}) => { a[type] = a[type] || {type, quantity: 0}; a[type].quantity += quantity || 0; return a; }, {}) console.log(Object.values(result));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM