0

I have the following Arrays:

this.originalSelectedRows = [1,2,3,4,5];
this.selectedRows = [3,4,5,6,7,8];

I want to know the following:

How many numbers are in this.originalSelectedRows, but not in this.selectedRows

Which in this case would be 2:

1 and 2

and how many numbers are in this.selectedRows, but not this.originalSelectedRows

Which in this case would be 3:

6, 7 and 8

I have the following, which works fine:

    let isOnListCount = 0;
    let isNotOnListCount = 0

    this.selectedRows.map((row) => {
      const isSelected = this.originalSelectedRows.filter(x => x === row);
        if(isSelected.length > 0)
          isOnListCount++;
        else
          isNotOnListCount++;
    });

But I want to know if this can be achieved in a neater fashion usng some of ES6's new features, or original JS

Alex
  • 3,730
  • 9
  • 43
  • 94

4 Answers4

2

You could take the length as counter and reduce the value with common items.

var array1 = [1, 2, 3, 4, 5],
    array2 = [3, 4, 5, 6, 7, 8],
    count1 = array1.length,
    count2 = array2.length;
    
array1.forEach(function (a) {
    if (array2.includes(a)) {
        count1--;
        count2--;
    }
});
console.log(count1, count2);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Readability is more important than short fancy code. You always have a way of making the most simple logic completely incomprehensible to new programmers. – Cerbrus Oct 13 '17 at 13:15
  • Specifically `&& (count1--, count2--)` is something new users will not recognize. `&&` as shortcut `if` and the `( , )` aren't common structures that they will recognize. – Cerbrus Oct 13 '17 at 13:26
  • @NinaScholz I know how much you wanted to use `reduce`, and write more obscure code. Here you go: `const common = arr.reduce((result, elt) => result + array2.includes(elt));`. Note the clever way we add a boolean. Now the answers are simply `array1.length - common` and `array2.length - common`. –  Oct 13 '17 at 17:09
  • @torazaburo, you know (i hope so), that i am able to write that in reduce style, but it is not necessary in this case (for saving a single line of code). – Nina Scholz Oct 13 '17 at 21:56
1

Sets will do a great job here :)

let set1 = new Set(this.originalSelectedRows)
let set2 = new Set(this.selectedRows)
let difference = new Set([...set1].filter(n => !set2.has(n)))

They are also relatively fast as well, but not as fast as a specially crafted solution :P

I am assuming that all of your items are unique though :)

user2662833
  • 1,005
  • 1
  • 10
  • 20
1

I'd convert one array into a set and than filter the other array for items which aren't in the set.

const
  valuesA = [1,2,3,4,5],
  valuesB = [3,4,5,6,7,8];
  
function getUniqueValues(sourceArray, testArray) {
  const 
    set = new Set(testArray);
    
  return sourceArray.filter(value => !set.has(value));
}

console.log(`Values in A and not in B: ${getUniqueValues(valuesA, valuesB)}`);
console.log(`Values in B and not in A: ${getUniqueValues(valuesB, valuesA)}`);
Thijs
  • 2,341
  • 2
  • 14
  • 22
0

You can just use Array#includes function to check if the element exists in the second array or not

const originalSelectedRows = [1,2,3,4,5];
const selectedRows = [3,4,5,6,7,8];

let isOnListCount = 0;
let isNotOnListCount = 0;

selectedRows.forEach(row => 
 originalSelectedRows.includes(row) ? isOnListCount++ : isNotOnListCount++
);

console.log(isOnListCount);
console.log(isNotOnListCount);
Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112