import { EqualityComparer, IEnumerable, IEnumerableFactory } from '../../types'; import { getKeySelectorAndComparer } from '../../utilities/utilityFunctions'; export function applyXor( factory: IEnumerableFactory, overrideKeySelector: ((item: TSource) => TKey) | null, src: Iterable, second: (Iterable | ((item: TSource) => TKey) | EqualityComparer)[] ): IEnumerable { function* generator(): Generator { const [others, keySelector, equalityComparer] = getKeySelectorAndComparer(overrideKeySelector, second); const setPairs: [Iterable, Set][] = [ [src, new Set([...src].map(keySelector))], ...others.map((other): [Iterable, Set] => [other, new Set([...other].map(keySelector))]) ]; const seenKeys = new Set(); for (const pair of setPairs) { const [source] = pair; for (const item of source) { const key = keySelector(item); if (seenKeys.has(key)) { continue; } seenKeys.add(key); let returnItem = true; for (const otherPair of setPairs) { if (pair === otherPair) { continue; } const [_, otherKeys] = otherPair; if (equalityComparer) { for (const otherKey of otherKeys) { if (equalityComparer(key, otherKey)) { returnItem = false; break; } } } else { if (otherKeys.has(key)) { returnItem = false; break; } } } if (returnItem) { yield item; } } } } return factory.createBasicEnumerable(generator); }