javascript - 如何改进和缩短以下比较两个数组并返回它们之间的对称差异的算法?
问题描述
在这个社区的一些帮助下,我创建了这个函数,我想知道我的if
陈述是否可以缩短或改进,因为我还是 JS 的新手,改进这个函数可以让我接触到新的知识。
请看下面的代码:
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));
解决方案
由于您实际上是对集合而不是数组进行操作,因此最好Set
明确使用对象。首先,让我们定义几个原语:
// 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)));
那么,对称差分运算可以很简单
// A d B = (A \ B) U (B \ A)
let difference = (a, b) => union(complement(a, b), complement(b, a))
如果你需要你的check
函数接受和返回数组,你可以这样定义它:
let check = (a, b) => [...difference(new Set(a), new Set(b))]
FWIW,这是一个带有基本集合操作的小型“库”:
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'))