diff --git a/src/index.js b/src/index.js index 2f88db7..6f34db4 100644 --- a/src/index.js +++ b/src/index.js @@ -32,6 +32,7 @@ export { hist } from "./hist/hist" export { i } from "./i/i" export { inc } from "./inc/inc" export { indexBy } from "./index-by/index-by" +export { intersect } from "./intersect/intersect" export { is, isNothing, isTrue, isFalse, isObject } from "./is/is" export { isEmpty, isNotEmpty } from "./is-empty/is-empty" export { isMatch } from "./is-match/is-match" diff --git a/src/intersect/intersect.js b/src/intersect/intersect.js new file mode 100644 index 0000000..fa2e9a5 --- /dev/null +++ b/src/intersect/intersect.js @@ -0,0 +1,26 @@ +import { findIndex } from "../find-index/find-index" + +export const intersect = (predicateFn, unionFn) => (aList, bList) => { + if (aList.length === 0) { + return bList + } + + if (bList.length === 0) { + return aList + } + + const result = [].concat(aList) + + for (let index = 0; index < bList.length; ++index) { + const b = bList[index] + const aIndex = findIndex(item => predicateFn(item, b))(result) + + if (aIndex === -1) { + result.push(b) + } else { + result[aIndex] = unionFn(result[aIndex], b) + } + } + + return result +} diff --git a/src/intersect/intersect.test.js b/src/intersect/intersect.test.js new file mode 100644 index 0000000..2efbbbd --- /dev/null +++ b/src/intersect/intersect.test.js @@ -0,0 +1,55 @@ +import test from "tape" + +import { intersect } from ".." + +test("array::intersect", t => { + t.deepEqual( + intersect( + (a, b) => a === b, + a => a + )([], [1, 2, 3]), + [1, 2, 3], + "First array empty" + ) + + t.deepEqual( + intersect( + (a, b) => a === b, + a => a + )([1, 2, 3], []), + [1, 2, 3], + "Second array empty" + ) + + t.deepEqual( + intersect( + (a, b) => a === b, + a => a + )([1, 2, 3], [3, 4, 5]), + [1, 2, 3, 4, 5], + "Join with common" + ) + + t.deepEqual( + intersect( + (a, b) => a === b, + a => a + )([1, 2], [3, 4, 5]), + [1, 2, 3, 4, 5], + "Join without common" + ) + + t.deepEqual( + intersect( + (a, b) => a.id === b.id, + (a, b) => ({ ...a, ...b }) + )( + [{ id: 1, overwrite: 1 }, { id: 2 }], + [{ id: 1, overwrite: 2 }, { id: 3 }] + ), + [{ id: 1, overwrite: 2 }, { id: 2 }, { id: 3 }], + "Join objects - same order as input arrays" + ) + + t.end() +})