-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathxorBy.ts
38 lines (35 loc) · 1.57 KB
/
xorBy.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import { identity } from '../util/identity';
import { iteratee } from '../util/iteratee';
import { last } from './last';
import { initial } from './initial';
import { isArrayLikeObject } from '../lang/isArrayLikeObject';
import { uniqBy } from './uniqBy';
import { flatten } from './flatten';
import { xor } from './xor';
type PropertyName = string | number | symbol;
type IterateeShorthand<T> = PropertyName | [PropertyName, any] | Partial<T>;
type ValueIterator<T, R> = (value: T) => R;
type ValueIterateeCustom<T, R> = ValueIterator<T, R> | IterateeShorthand<T>;
function xorBy<T>(array: T[], predicate: ValueIterateeCustom<T, unknown>): T[];
function xorBy<T>(array1: T[], array2: T[], predicate: ValueIterateeCustom<T, unknown>): T[];
function xorBy<T>(...args: [...arrays: T[][], predicate: ValueIterateeCustom<T, unknown>]): T[];
function xorBy<T>(...args: [...arrays: T[][], predicate: ValueIterateeCustom<T, unknown>]): T[] {
let predicate = last(args);
if (isArrayLikeObject(predicate)) {
return xor(...(args as T[][]));
}
if (predicate === undefined) {
predicate = identity;
}
const iterativeFunc = iteratee(predicate);
const arrays = initial(args) as T[][];
const uniqedArrays = arrays.map((array) => uniqBy(array, iterativeFunc));
const flattened = flatten<T>(uniqedArrays);
return flattened.filter(
(arrVal, arrIndex, collection) =>
!collection.find(
(othVal, othIndex) => arrIndex !== othIndex && Object.is(iterativeFunc(arrVal), iterativeFunc(othVal))
)
);
}
export { xorBy };