【问题标题】:remove common elements between multiple arrays删除多个数组之间的公共元素
【发布时间】:2021-03-30 15:19:00
【问题描述】:

我有 3 个数组(或更多/更少,不是必须为 3,我只是举了一个例子),我想删除它们之间的所有公共元素。例如,在第一个 2 之间,公共元素是 x and z,在第二个和第三个数组之间,公共元素是 t。在第一个和第三个之间的共同元素是k。基本上我想删除在多个数组中出现超过 1 次的任何元素。

!!第一个数组可以和第三个数组有共同的元素!!

这是我迄今为止尝试过的,但它无法正常工作。

let y = [{
    id: 'a',
    elems: ['x', 'y', 'z', 'k']
  },
  {
    id: 'b',
    elems: ['x', 't', 'u', 'i', 'z']
  },
  {
    id: 'c',
    elems: ['m', 'n', 'k', 'o', 't']
  },
]

// x, z, t

for (let i = 0; i < y.length - 1; i++) {
  let current = y[i].elems
  let current2 = y[i + 1].elems

  if (current[i] == current2[i]) {
    const index = current.indexOf(current[i]);
    if (index > -1) {
      current.splice(index, 1);
      current2.splice(index, 1);
    }
  }
}

console.log(y)

想要的结果是

[
  {

    "id": "a",
    "elems": [
      "y"
    ]
  },
  {
    "id": "b",
    "elems": [
      "u",
      "i"
    ]
  },
  {
    "id": "c",
    "elems": [
      "m",
      "n",
      "o"
    ]
  }
]

这将是一个正确和最佳的解决方案?我还尝试连接 3 个数组并删除重复项,但后来我不知道如何重新创建 3 个数组。谢谢!

【问题讨论】:

  • 对不起,那里没用。我会删除它

标签: javascript arrays duplicates


【解决方案1】:

我会首先遍历所有元素并计算已经看到的次数。之后,我会再次循环并过滤掉多次看到的任何内容。

const myData = [{
    id: 'a',
    elems: ['x', 'y', 'z']
  },
  {
    id: 'b',
    elems: ['x', 't', 'u', 'i', 'z']
  },
  {
    id: 'c',
    elems: ['m', 'n', 'o', 't']
  },
]

// count up every elem so we know which ones are duplicated
const allElems = myData.reduce((acc, item) => {
  item.elems.forEach( key => { 
    acc[key] = acc[key] || 0;
    acc[key]++;
  });
  return acc;
}, {})

// loop over all the elems and select only the elems that we have seen once
myData.forEach(item => {
  item.elems = item.elems.filter(key => allElems[key] === 1);
})

console.log(myData)

【讨论】:

    【解决方案2】:

    let x = ['a', 'b']
    let y = [{
        id: 'a',
        elems: ['x', 'y', 'z', 'k']
      },
      {
        id: 'b',
        elems: ['x', 't', 'u', 'i', 'z']
      },
      {
        id: 'c',
        elems: ['m', 'n', 'k', 'o', 't']
      },
    ]
    
    
    // x, z, t
    
    for (let i = 0; i < y.length - 1; i++) {
      for (let j = 1; j < y.length; j++) {
        let current = y[i].elems
        let current2 = y[j].elems
    
        current2.forEach((item,index)=>{
          if(current.includes(item)){
            current.splice(current.indexOf(item),1)
            current2.splice(index,1)
          }
        })
      }
    }
    
    console.log(y)
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 有一件事我忘了提,我正要编辑我的帖子,第一个数组也可以与第三个数组有共同的元素。在这个实现中,这种情况不起作用:(
    • 代码已更新..请检查..如果您发现任何问题,请告诉我。
    【解决方案3】:

    const y = [
      { id: 'a', elems: ['x', 'y', 'z'] },
      { id: 'b', elems: ['x', 't', 'u', 'i', 'z'] },
      { id: 'c', elems: ['m', 'n', 'o', 't'] },
    ];
    
    // get number of occurences for each elem
    const elems 
      = y.flatMap(e => e.elems).reduce((acc,elem) => { 
          acc[elem] = acc[elem] ? acc[elem]+1 : 1; 
          return acc;
        }, {});
          
    // get unique elems
    const unique = Object.keys(elems).filter(elem => elems[elem]===1);
    
    // remove non-unique elems from each item
    const res = y.map(item => 
      ({ ...item, elems: item.elems.filter(e => unique.includes(e)) })
    );
    
    console.log(res);

    【讨论】:

      【解决方案4】:

      在一个循环后使用 Map 跟踪计数,然后在过滤器中使用该 Map 的计数以获得最终结果

      let x = ['a', 'b']
      let y = [{
          id: 'a',
          elems: ['x', 'y', 'z']
        },
        {
          id: 'b',
          elems: ['x', 't', 'u', 'i', 'z']
        },
        {
          id: 'c',
          elems: ['m', 'n', 'o', 't']
        },
      ]
      
      const counts = new Map()
      // first iteration to count values
      y.forEach(({ elems }) => elems.forEach(v => counts.set(v, (counts.get(v) || 0) + 1)));
      // second iteration to filter out dups 
      y.forEach(e => e.elems = e.elems.filter(v => counts.get(v) === 1))
      
      
      console.log(y)

      【讨论】:

        【解决方案5】:

        让我知道这是否适合你。

        let y = [
          {
            id: "a",
            elems: ["x", "y", "z", "k"],
          },
          {
            id: "b",
            elems: ["x", "t", "u", "i", "z"],
          },
          {
            id: "c",
            elems: ["m", "n", "x", "z", "t"],
          },
        ];
        
        // For every element in first array
        for (let el of y[0].elems) {
        
          //If we find that every other array includes it
          if (y.every((obj) => obj.elems.includes(el))) {
        
            //Remove it from all arrays
            for (let obj of y) {
              obj.elems = obj.elems.filter((x) => x !== el);
            }
          }
        }
        

        【讨论】:

          【解决方案6】:

          let y = [{
              id: 'a',
              elems: ['x', 'y', 'z']
          },
          {
              id: 'b',
              elems: ['x', 't', 'u', 'i', 'z']
          },
          {
              id: 'c',
              elems: ['m', 'n', 'o', 't']
          },
          ];
          //
          
          const notExist = (x, arr) => !arr.find(el => el == x);
          const restToArrays = (i, arr) => arr.reduce((a, b, index) => index == i ? a : [...a, ...b.elems], []);
          const result = y.map((ligne, index, arr) => ({
              id: ligne.id,
              elems: ligne.elems.filter(v => notExist(v, restToArrays(index, arr)))
          }))
          
          console.log(result);

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-07-20
            • 1970-01-01
            • 2018-03-15
            • 2016-03-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多