【问题标题】:Merge two arrays and modify them in place (javascript) [duplicate]合并两个数组并就地修改它们(javascript)[重复]
【发布时间】:2021-01-02 13:51:33
【问题描述】:

我有两个对象数组,原始的和选定的,像这样:

original =[{ id: 4 , quantity: 4 },{ id: 2 , quantity: 2 },{ id: 76 , quantity: 2 }]
selected = [{ id: 2 , quantity: 1 }, { id: 100 , quantity: 7 }]

我希望能够在 id 上合并这些数组,如果它们有相似的 id 我应该总结数量,

在这种情况下,生成的数组应如下所示:

result=[{ id: 4 , quantity: 4 },{ id: 2 , quantity: 3 },{ id: 76 , quantity: 2 } , { id: 100 , quantity: 7 }]

我想过做这样的事情:

 const result =original.map(o => ({
            ...selectedArray.findIndex((s) => {(s.id === o.id) && selected)? return }
            ...original
         }));

但我不确定我应该如何添加数量,任何帮助或资源都将不胜感激。

【问题讨论】:

    标签: javascript arrays reactjs javascript-objects


    【解决方案1】:

    这是一个简单易懂的最佳解决方案,运行时间为O(n+m)。如果您的数组大小很大,您应该使用它。其中nm 是数组originalselected 的长度。

    let original =[{ id: 4 , quantity: 4 },{ id: 2 , quantity: 2 },{ id: 76 , quantity: 2 }];
    let selected = [{ id: 2 , quantity: 1 }, { id: 100 , quantity: 7 }];
    
    let obj = Object.fromEntries(original.map(e => [e.id, e]));
    
    selected.forEach(e => {
       if (obj[e.id]) {
           obj[e.id].quantity += e.quantity;
       } else {
           obj[e.id] = e;
       }
    });
    
    let result = Object.values(obj);
    
    console.log(result);

    【讨论】:

    • 这看起来不是对它们求和:"id": 2, "quantity": 1
    • 感谢修复@claytronicon
    • 非常感谢您的详细回答:)
    【解决方案2】:

    您可以找到该对象并更新quantity 或推送一个新对象。

    const 
        original = [{ id: 4, quantity: 4 }, { id: 2, quantity: 2 }, { id: 76, quantity: 2 }],
        selected = [{ id: 2, quantity: 1 }, { id: 100, quantity: 7 }],
        merged = [...original, ...selected].reduce((r, { id, quantity }) => {
            const item = r.find(q => q.id === id);
            if (item) item.quantity += quantity;
            else r.push({ id, quantity });
            return r;
        }, []);
    
    console.log(merged);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    使用哈希表的解决方案。

    const 
        mergeTo = (target, reference = {}) => ({ id, quantity }) => {
            if (reference[id]) reference[id].quantity += quantity;
            else target.push(reference[id] = { id, quantity });
        },
        original = [{ id: 4, quantity: 4 }, { id: 2, quantity: 2 }, { id: 76, quantity: 2 }],
        selected = [{ id: 2, quantity: 1 }, { id: 100, quantity: 7 }],
        merged = [],
        merge = mergeTo(merged);
    
    
    original.forEach(merge);
    selected.forEach(merge);
    
    console.log(merged);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 一个问题,然而,在性能方面,有没有比另一个更好?
    • 第二个具有更好的性能,因为 O(1) 访问对象而没有在 O(n) 的数组中找到。
    【解决方案3】:

    我不认为这不是好方法,但我认为这会奏效。

     selected.forEach(obj => {
      var exists = original.find(x => x.id === obj.id);
      if(exists) {
        exists.quantity += obj.quantity;
      } else {
        original.push(obj);
      }
    });
    
    console.log(original);
    

    【讨论】:

    • 老实说,这是我最初的方法,但我正在考虑使用 es6,但感谢您的回答 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    相关资源
    最近更新 更多