0

I have created this function, with some assistance in this community and I would like to know if my if statements could be shortened or improved as I am still new to JS and refining this function could open me to new knowledge.

Please see the code below:

let jo = [1,2,3,5,6]
let ji = [1,2,3,5,4]

const checker = (arr1, arr2) => {
   
    return arr1.every(num => arr2.includes(num)) == false && 
    arr2.every(num => arr1.includes(num)) == false ? 
    Array.from(new Set(arr1.filter(x => !new Set(arr2).has(x))))
    .concat(Array.from(new Set(arr2.filter(x => !new Set(arr1).has(x))))) :
    arr1.every(num => arr2.includes(num)) == false? 
    Array.from(new Set(arr1.filter(x => !new Set(arr2).has(x)))) :
     arr2.every(num => arr1.includes(num)) == false ?
     Array.from(new Set(arr2.filter(x => !new Set(arr1).has(x)))) :
     "no discrepancies"
}

console.log(checker(jo, ji));
Kobe
  • 6,226
  • 1
  • 14
  • 35
Arp
  • 979
  • 2
  • 13
  • 30
  • 1
    Take a look here https://stackoverflow.com/a/33034768/5378743 – Roland Starke Oct 30 '19 at 13:36
  • `let difference = arrA .filter(x => !arrB.includes(x)) .concat(arrB.filter(x => !arrA.includes(x)));` – Martin Wickman Oct 30 '19 at 14:15
  • 3
    @Prune While this may be on-topic on CR in the future, please don't use the existence of the CR site as a reason to close a question. Evaluate the request and use a reason like *too broad*, *primarily opinion-based*, etc. Then you can mention to the OP that it can be posted on Code Review if it is [on-topic](https://codereview.stackexchange.com/help/on-topic). Please see the section **What you should not do** in [this answer to _A guide to Code Review for Stack Overflow users_](https://codereview.meta.stackexchange.com/a/5778/120114) – Sᴀᴍ Onᴇᴌᴀ Oct 30 '19 at 17:10
  • @SᴀᴍOnᴇᴌᴀ: thanks! I haven't read the CR standards for over a year. My apologies, and thanks for the update. – Prune Oct 30 '19 at 17:12

1 Answers1

2

Since you actually operate on sets and not arrays, it's better to use Set objects explicitly. First, let's define a couple of primitives:

// A U B
let union = (a, b) => new Set([...a, ...b]);

// A \ B
let complement = (a, b) => new Set([...a].filter(x => !b.has(x)));

then, the symmetric difference operation can be simply

// A d B = (A \ B) U (B \ A)
let difference = (a, b) => union(complement(a, b), complement(b, a))

If you need your check function to accept and return arrays, you can define it like this:

let check = (a, b) => [...difference(new Set(a), new Set(b))]

FWIW, here's a small "library" with basic set operations:

const
    _set = x => x instanceof Set ? x : set.from(x),
    _has = s => Set.prototype.has.bind(_set(s)),
    _array = x => Array.isArray(x) ? x : [...x],
    _not = f => x => !f(x),
    _empty = s => s.size === 0,
    _everyfn = fns => x => fns.every(f => f(x));

const set = {};

set.from = x => new Set(x);
set.of = (...args) => set.from(args);

set.union = (...args) => set.from(args.map(_array).flat());
set.intersection = (a, ...rest) => set.from(_array(a).filter(_everyfn(rest.map(_has))));
set.complement = (a, b) => set.from(_array(a).filter(_not(_has(b))));
set.difference = (a, b) => set.union(set.complement(a, b), set.complement(b, a));
set.includes = (a, b) => _empty(set.complement(b, a));

// examples:

console.log(...set.union('abc', 'abxy', 'abz'))
console.log(...set.intersection('abc', 'abxy', 'abz'))
console.log(...set.complement('abcd', 'abxy'))
console.log(...set.difference('abcd', 'abxy'))
console.log(set.includes('abcd', 'ac'))
console.log(set.includes('abcd', 'ax'))
georg
  • 211,518
  • 52
  • 313
  • 390
  • is this *O(n)*? – marzelin Oct 30 '19 at 14:15
  • 2
    @marzelin `union` is `O(m+n)` as it needs to go through two sets of size `m` and `n`. `complement` is `O(n)` since `b` is a Set with `O(1)` lookup, so you only need to care about the size of `a`. `difference` does an `O(n)` operation and `O(m)` operation (`complement` twice) and feeds it into an `O(m+n)` operation. This simplifies (if I am not mistaken) to `O(m+n)` again. Finally `check` is an `O(n)` operation (spread) on the result of the `O(m+n)` operation (`difference`). This should still be `O(m+n)`. We can simplify further and just call it `O(n)` since it's all going to be linear. – VLAZ Oct 31 '19 at 07:57