代码之家  ›  专栏  ›  技术社区  ›  xkeshav

两个对象数组相交,只保留匹配元素,根据对象键删除不匹配元素

  •  1
  • xkeshav  · 技术社区  · 6 年前

    我有两个对象数组,我需要在这些数组之间相交,找出共同的一个,并从第一个数组中删除它,该数组基于其中一个键不具有相同的项。

    注意,我想改变第一个数组本身。

    这是我的代码示例和我尝试的 .map 但没有得到预期的结果。

    (() => {
      const first = Array.from({ length: 5 }, (_, i) => ({
        id: `in-${i}`,
        name: "one",
        age: `${i * 5}`
      }));
    
      const second = Array.from({ length: 3 }, (_, i) => ({
        id: `in-${i}`,
        name: "two"
      }));
      console.log({ first });
      console.log({ second });
      const sid = second.map(s => s.id);
    
      first.map((f, i) => {
        if (sid.includes(f.id)) {
          console.log("✔️ included");
        } else {
          console.log("👎🏻 not included");
          first.splice(i, 1);
        }
      });
      console.log("...now...");
      console.log({ first });
      console.log({ second });
    })();

    这不会删除第一个数组的最后一个数组元素。

    预期产量:

    [ { id: 'in-0', name: 'one', age: '0' },
      { id: 'in-1', name: 'one', age: '5' },
      { id: 'in-2', name: 'one', age: '10' }
    ] }
    

    实际产量:

    [ { id: 'in-0', name: 'one', age: '0' },
      { id: 'in-1', name: 'one', age: '5' },
      { id: 'in-2', name: 'one', age: '10' },
      { id: 'in-4', name: 'one', age: '20' } ] }
    

    我在这里犯了什么错?请帮忙。

    另外,建议任何其他简短的方法。我想我可以用 .reduce /但我不知道怎么做。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Pointy    6 年前

    当超过元素2时,回调将删除元素3。这是数组中的索引4,因此下一次迭代将删除元素5。元素4被跳过,因为 .map() 不知道你在改变数组。

    我个人会用一个简单的 for 如果不想创建新数组,请循环:

    for (let i = first.length; --i >= 0; ) {
      if (!sid.includes(first[i].id))
        first.splice(i, 1);
    }
    

    如果你从最后循环到开始,拼接元素不会把事情搞砸。

        2
  •  3
  •   Taki    6 年前

    你可以用 .filter()

    const result = first.filter(f => sid.includes(f.id) );
    

    如果你想变异 first 数组,不要使用 const ,替换为 let 重写如下:

    first = first.filter(f => sid.includes(f.id));
    

    (() => {
      // replace const with let
      let first = Array.from({
        length: 5
      }, (_, i) => ({
        id: `in-${i}`,
        name: "one",
        age: `${i * 5}`
      }));
    
      const second = Array.from({
        length: 3
      }, (_, i) => ({
        id: `in-${i}`,
        name: "two"
      }));
    
      const sid = second.map(s => s.id);
    
      // use .filter and overwrite the first array
      first = first.filter(f => sid.includes(f.id));
    
      console.log(first);
    
    })();