3

I want to get the exact difference between two string arrays.

const array1 = ['T','E','A','P','A','P','E','R'];
const array2 = ['T','A','P'];

Expected Output Array:

['E','A','P','E','R']

I have tried this method:

const output = array1.filter(char => array2.includes(char));

But that removes all instances of a character, like:

['E','E','R']

I'm a newbie, so could you guide me to the right direction?

Fallc
  • 115
  • 1
  • 8
  • 2
    Whats the result for `["A", "B"] ["B", "A"]` ? – Jonas Wilms Apr 20 '19 at 13:16
  • Should be an empty array. – Fallc Apr 20 '19 at 13:19
  • Why? Whats the logic behind that? – Jonas Wilms Apr 20 '19 at 13:19
  • I basically have a character array of words (array1). If the user types something in, the character gets added to a used character array. The user is only allowed to type the characters in array1 and if one gets used up, he can't type it in anymore. So I have to have an array with allowed characters, which I use for input control. – Fallc Apr 20 '19 at 13:25
  • Possible duplicate of [get difference between two arrays (including duplicates)](https://stackoverflow.com/questions/39810641/get-difference-between-two-arrays-including-duplicates) – adiga Apr 20 '19 at 13:28

3 Answers3

6

You could take a closure over the index for the second array and increment the index and remove this item from the result set.

var array1 = ['T', 'E', 'A', 'P', 'A', 'P', 'E', 'R'],
    array2 = ['T', 'A', 'P'],
    result = array1.filter((i => v => array2[i] !== v || !++i)(0));

console.log(result);

A different approach without a predefined order of array2.

var array1 = ['T', 'E', 'A', 'P', 'A', 'P', 'E', 'R'],
    array2 = ['T', 'A', 'P'],
    set2 = new Set(array2)
    result = array1.filter(v => !set2.delete(v));

console.log(result);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

I think filter is not correct apparoch here. Because there are some elements repeadted. Use a simple for-loop. And remove the elements when you add it to result.

const array1 = ['T','E','A','P','A','P','E','R'];
const array2 = ['T','A','P'];
const copy = [...array2];

let res = [];
for(let i = 0;i<array1.length;i++){
  let index = copy.indexOf(array1[i]);
  if(index === -1){
    res.push(array1[i]);
  }
  else copy.splice(index,1);
  

}
console.log(res)
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
1

You could remove elements from allowed based on the input array:

 const allowed = ['T','E','A','P','A','P','E','R'];
 const input = ['T','A','P'];

 for(const char of input) {
   const pos = allowed.indexOf(char);
   if(pos === -1) {
     // char doesnt exist?
   } else {
     allowed.splice(pos, 1);
   }
 }

Then allowed will be your expected result at the end.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151