How to find difference between two same array in JS?

Viewed 108

I want to find difference between two arrays. I tried below code from one of the solution given on SF community, but not working from me.

My below code is not working if there is number repeated EVEN NUMBER of time(like "7" repeated twice in both the arrays a & b and in result I am getting "7" as difference),

whereas code is working for number repeated ODD NUMBER of time(like "11" repeated thrice in both the arrays a & b and in result it cancel all the "11" and return nothing for this).

I want the solution to find difference or cancels the number repeated ANY NUMBER of times, I mean if number like "7" repeated twice in both the arrays then it should cancels both the number and return NOTHING.

And given two arrays are, you can find more examples like "7" and "11" in belows given arrays

a = ["1", "3", "17", "12", "11", "17", "7", "7", "85", "16", "5", "30", "11", "81", "20", "49", "8", "17", "11", "8", "13", "81"]

b = ["5", "20", "78", "13", "85", "81", "12", "17", "16", "8", "17", "3", "7", "1", "11", "9", "8", "17", "49", "30", "81", "11", "11", "7"]

Below is the code I am using to find difference between two arays,

function arr_diff (a1, a2) {

var a = [], diff = [];

for (var i = 0; i < a1.length; i++) {
    a[a1[i]] = true;
}

for (var i = 0; i < a2.length; i++) {
    if (a[a2[i]]) {
        delete a[a2[i]];
    } else {
        a[a2[i]] = true;
    }
}

for (var k in a) {
    diff.push(k);
}

console.log(diff);
return diff;
}

DIFFERENCE/RESULT : I get from two arrays is : ["7", "8", "9", "78", "81", "getUnique"]

EXPECTED RESULT : from two arrays I want : ["9", "78"]

Please help, any help will be appreciated.

5 Answers

In your code what is happening,

First time it checks for 7, then it removes from a. Now when next time it checks for same, since it is removed from a, it sets true in a. Same for other consecutive numbers.

You should do something like this

var a1 = ["1", "3", "17", "12", "11", "17", "7", "7", "85", "16", "5", "30", "11", "81", "20", "49", "8", "17", "11", "8", "13", "81"]

var a2  = ["5", "20", "78", "13", "85", "81", "12", "17", "16", "8", "17", "3", "7", "1", "11", "9", "8", "17", "49", "30", "81", "11", "11", "7"]

function arr_diff (a1, a2) {

var a = {}, diff = [], newArr = [];

for (var i = 0; i < a1.length; i++) {
    a[a1[i]] = true;
}

for (var i = 0; i < a2.length; i++) {
    if (a[a2[i]]) {
//         delete a[a2[i]];
    } else {
        newArr[a2[i]] = true;
    }
}

for (var k in newArr) {
    diff.push(k);
}

console.log(diff);
return diff;
}

arr_diff(a1, a2)

What I did is, I am creating a new Array (newArr) which will store only unique numbers

a = ["1", "3", "17", "12", "11", "17", "7", "7", "85", "16", "5", "30", "11", "81", "20", "49", "8", "17", "11", "8", "13", "81"]
b = ["5", "20", "78", "13", "85", "81", "12", "17", "16", "8", "17", "3", "7", "1", "11", "9", "8", "17", "49", "30", "81", "11", "11", "7"]
let difference = a
                 .filter(x => !b.includes(x))
                 .concat(b.filter(x => !a.includes(x)));

console.log(difference);

This will fix your problem

const difference = a
                 .filter(x => !b.includes(x))
                 .concat(b.filter(x => !a.includes(x)));

Try this, let me know if it works for you

let a = ["1", "3", "17", "12", "11", "17", "7", "7", "85", "16", "5", "30", "11", "81", "20", "49", "8", "17", "11", "8", "13", "81"]

let b = ["5", "20", "78", "13", "85", "81", "12", "17", "16", "8", "17", "3", "7", "1", "11", "9", "8", "17", "49", "30", "81", "11", "11", "7"];

function arr_diff(a1,a2){
    let a = [...a1];
    let b = [...a2];

    let c = [];
    for(let i=0; i < b.length; i++){
        if(a.includes(b[i])) {b.splice(i, 1);}
        else c.push(b[i]);
    }

console.log(c);
return c;
}

arr_diff(a,b)

If you want to keep the extra values in the difference array too, ex. for

a = [1,1,1,1]
b = [1]

the result: [1,1,1], I'd do this: count occurrences in first array and subtract the count from the second array.

function getDifference(array1, array2) {
  const counter = {}
  const result = []

  function addNumberToCounter(number) {
    const currentCount = counter[number] || 0
    counter[number] = currentCount + 1
  }
  function subtractNumberFromCounter(number) {
    const currentCount = counter[number] || 0
    counter[number] = currentCount - 1
  }
  function addNumberToResult(number, times) {
    for(let i = 0; i < times; i++) {
      result.push(number)
    }
  }
  
  array1.forEach(addNumberToCounter)
  array2.forEach(subtractNumberFromCounter)
  
  for (let number in counter) {
    const numberCount = Math.abs(counter[number])
    addNumberToResult(number, numberCount)
  }
  
  return result
}

const a = ["1", "3", "17", "12", "11", "17", "7", "7", "85", "16", "5", "30", "11", "81", "20", "49", "8", "17", "11", "8", "13", "81"]
const b = ["5", "20", "78", "13", "85", "81", "12", "17", "16", "8", "17", "3", "7", "1", "11", "9", "8", "17", "49", "30", "81", "11", "11", "7"]
const result = getDifference(a, b)
console.log(result)

For your code to work you could use Set to deduplicate values first

a = ["1", "3", "17", "12", "11", "17", "7", "7", "85", "16", "5", "30", "11", "81", "20", "49", "8", "17", "11", "8", "13", "81"]

b = ["5", "20", "78", "13", "85", "81", "12", "17", "16", "8", "17", "3", "7", "1", "11", "9", "8", "17", "49", "30", "81", "11", "11", "7"]

 var set1=new Set([...a]) // remove duplicates from each array
 var set2=new Set([...b])
 a1=[...set1]
 a2=[...set2]

function arr_diff (a1, a2) {

  var a = [], diff = [];
  
  for (var i = 0; i < a1.length; i++) {
      a[a1[i]] = true;
  }
  
  for (var i = 0; i < a2.length; i++) {
      if (a[a2[i]]) {
          delete a[a2[i]];
      } else {
          a[a2[i]] = true;
      }
  }
  
  for (var k in a) {
      diff.push(k);
  }
  
  console.log(diff);
  return diff;
  }

  arr_diff (a1, a2)

Alternatively you could use filter and some

a = ["1", "3", "17", "12", "11", "17", "7", "7", "85", "16", "5", "30", "11", "81", "20", "49", "8", "17", "11", "8", "13", "81"]

b = ["5", "20", "78", "13", "85", "81", "12", "17", "16", "8", "17", "3", "7", "1", "11", "9", "8", "17", "49", "30", "81", "11", "11", "7"]

res=b.filter(n=>!a.some(u=>n==u))
console.log(res)

Related