简体   繁体   中英

remove common elements between multiple arrays

I have 3 arrays (or more/less, it's not mandatory to be 3, I just gave an example) and I want to remove all the common elements between them. For example, between the first 2, the common elements are x and z , between the second and the third array the common element would be t . Between the first and the thirs the common element is k . Basically I want to remove any elements that appear more than 1 times in multiple arrays.

!! the first array can have common elements with the third one !!

Here is what I tried so far, but it's not working correctly.

 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)

The desired result would be

[
  {

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

Which would be a correct and optimal solution for this? I also tried to concatenate the 3 arrays and remove the duplicates, but then I don't know how to recreate the 3 arrays back.. Thanks!

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

I would first loop over all the elems and count up how many times that have been seen. After that I would loop again and filter out anything that was seen more than once.

 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)

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

Using a Map to track counts after one loop through then use the count of that Map in a filter for final results

 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)

Let me know if this works for you.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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