diff --git a/__tests__/Array/differenceWith.test.ts b/__tests__/Array/differenceWith.test.ts new file mode 100644 index 0000000..9615881 --- /dev/null +++ b/__tests__/Array/differenceWith.test.ts @@ -0,0 +1,48 @@ +import { expectType } from 'ts-expect' + +import { A, D, F, O, flow, pipe } from '../..' + +type Obj = { + readonly a?: number + readonly b?: number + readonly c?: number +} + +describe('differenceWith', () => { + it('provides correct types', () => { + expectType>( + A.differenceWith(['', 'hello', 'world'],[''], F.identity), + ) + }) + + it('returns a correct result', () => { + expect( + A.differenceWith([{ a: 1 }, { b: 2 }],[{ a: 1 }, { c: 3 }], F.identity), + ).toEqual([{ b: 2 }]) + expect( + A.differenceWith<{a:number}>([{a:1}, {a:2}], [{a:1}], D.get('a')) + ).toEqual([{a:2}]) + expect( + A.differenceWith([{a:{a1:1}}, {a:{a1:2}}], [{a:{a1:1}}], D.get('a')) + ).toEqual([{a:{a1:2}}]) + expect( + A.differenceWith([{a:{a1:1}}, {a:{a1:2}}], [{a:{a1:1}}], flow(D.get('a'),O.flatMap(D.get('a1')))) + ).toEqual([{a:{a1:2}}]) + }) + + it('*', () => { + expect(A.differenceWith([1, 2, 3, 4],[3, 4, 5, 6], F.identity)).toEqual([1, 2]) + }) +}) + +describe('difference (pipe)', () => { + it('provides correct types', () => { + expectType>( + pipe([5, 2, 3, 5, 6], A.differenceWith([5, 2, 3, 1, 5, 4],F.identity)), + ) + }) + + it('*', () => { + expect(pipe([5, 2, 3, 5, 6], A.differenceWith([5, 2, 3, 1, 5, 4],F.identity))).toEqual([6]) + }) +}) diff --git a/docs/api/generated/_array.mdx b/docs/api/generated/_array.mdx index 5307aa4..c4bd42f 100644 --- a/docs/api/generated/_array.mdx +++ b/docs/api/generated/_array.mdx @@ -106,6 +106,21 @@ A.difference([1, 2, 3, 4], [3, 4, 5, 6]) // → [1, 2] pipe([5, 2, 3, 5, 6], A.difference([5, 2, 3, 1, 5, 4])) // → [6] ``` +### differenceWith + +Returns elements from the first array, not existing in the second array, based on a comparison function. + + +```ts +function differenceWith(xs: Array, ys: Array, fn: (x: A) => unknown): Array +function differenceWith(ys: Array, fn: (x: A) => unknown): (xs: Array) => Array +``` + +```ts +A.differenceWith([1, 2, 3, 4],[3, 4, 5, 6], F.equals) // → [1, 2] +pipe([5, 2, 3, 5, 6], A.differenceWith([5, 2, 3, 1, 5, 4],F.equals)) // → [6] +``` + ### drop Returns a new array that does not contain the first `n` elements of the provided array, or an empty array if `n` is either less than `0` or greater than the length of the provided array. diff --git a/src/Array/Array.res b/src/Array/Array.res index 670e05f..3671a28 100644 --- a/src/Array/Array.res +++ b/src/Array/Array.res @@ -662,6 +662,15 @@ let any = (xs, predicateFn) => Belt.Array.someU(xs, (. value) => predicateFn(val @gentype let difference = (xs, ys) => xs->uniq->reject(value => includes(ys, value)) +%comment( + "Returns elements from the first array, not existing in the second array, based on a comparison function." +) +@gentype +let differenceWith = (xs, ys, selectFn) => { + let _ys = ys->uniq->Belt.Array.map(selectFn) + xs->uniq->reject(value => _ys->Belt.Array.someU((. y) => y == selectFn(value))) +} + %comment("Returns union of two arrays.") @gentype let union = (xs, ys) => xs->concat(ys)->uniq diff --git a/src/Array/Array.ts b/src/Array/Array.ts index 0c91816..c5dbe89 100644 --- a/src/Array/Array.ts +++ b/src/Array/Array.ts @@ -55,3 +55,8 @@ export declare function flatMap( xs: Array, fn: (value: A) => B | Array, ): Array +export declare function differenceWith( + xs: Array, + ys: Array, + fn: (x: A) => unknown, +): Array \ No newline at end of file diff --git a/src/Array/index.ts b/src/Array/index.ts index add79e0..3129483 100644 --- a/src/Array/index.ts +++ b/src/Array/index.ts @@ -782,6 +782,19 @@ export declare function difference(ys: Array): (xs: Array) => Array export declare function difference(xs: Array, ys: Array): Array +/** Returns elements from the first array, not existing in the second array, based on a comparison function. */ + +export declare function differenceWith( + xs: Array, + ys: Array, + fn: (x: A) => unknown, +): Array + +export declare function differenceWith( + ys: Array, + fn: (x: A) => unknown, +): (xs: Array) => Array + /** Returns union of two arrays. */ export declare function union(ys: Array): (xs: Array) => Array