67 lines
1.5 KiB
JavaScript
67 lines
1.5 KiB
JavaScript
((a, b) => {
|
|
'use strict';
|
|
|
|
|
|
let // UNION AND DIFFERENCE
|
|
|
|
// union :: [a] -> [a] -> [a]
|
|
union = (xs, ys) => unionBy((a, b) => a === b, xs, ys),
|
|
|
|
// difference :: [a] -> [a] -> [a]
|
|
difference = (xs, ys) =>
|
|
ys.reduce((a, y) =>
|
|
a.indexOf(y) !== -1 ? (
|
|
delete_(y, a)
|
|
) : a.concat(y), xs),
|
|
|
|
|
|
|
|
// GENERAL PRIMITIVES
|
|
|
|
// unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
|
|
unionBy = (f, xs, ys) => {
|
|
let sx = nubBy(f, xs),
|
|
sy = nubBy(f, ys);
|
|
|
|
return sx.concat(
|
|
sx
|
|
.reduce(
|
|
(a, x) => deleteBy(f, x, a),
|
|
sy
|
|
)
|
|
)
|
|
},
|
|
|
|
// deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
|
|
deleteBy = (f, x, xs) =>
|
|
xs.reduce((a, y) => f(x, y) ? a : a.concat(y), []),
|
|
|
|
// delete_ :: a -> [a] -> [a]
|
|
delete_ = (x, xs) =>
|
|
deleteBy((a, b) => a === b, x, xs),
|
|
|
|
// nubBy :: (a -> a -> Bool) -> [a] -> [a]
|
|
nubBy = (f, xs) => {
|
|
let x = (xs.length ? xs[0] : undefined);
|
|
|
|
return x !== undefined ? [x].concat(
|
|
nubBy(f, xs.slice(1)
|
|
.filter(y => !f(x, y))
|
|
)
|
|
) : [];
|
|
};
|
|
|
|
|
|
|
|
// 'SYMMETRIC DIFFERENCE'
|
|
|
|
return union(
|
|
difference(a, b),
|
|
difference(b, a)
|
|
);
|
|
|
|
})(
|
|
["John", "Serena", "Bob", "Mary", "Serena"],
|
|
["Jim", "Mary", "John", "Jim", "Bob"]
|
|
);
|