From 9072cbe01bd1ebd0028421c6abf78a65d89ee4bf Mon Sep 17 00:00:00 2001 From: Minsang Kim Date: Tue, 13 Feb 2024 13:28:46 +0900 Subject: [PATCH 1/2] feat: added A.differenceWith --- __tests__/Array/differenceWith.test.ts | 39 ++++++++++++++++++++++++++ docs/api/generated/_array.mdx | 15 ++++++++++ src/Array/Array.res | 9 ++++++ src/Array/index.ts | 13 +++++++++ 4 files changed, 76 insertions(+) create mode 100644 __tests__/Array/differenceWith.test.ts diff --git a/__tests__/Array/differenceWith.test.ts b/__tests__/Array/differenceWith.test.ts new file mode 100644 index 0000000..5beed5d --- /dev/null +++ b/__tests__/Array/differenceWith.test.ts @@ -0,0 +1,39 @@ +import { expectType } from 'ts-expect' + +import { A, F, 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.equals), + ) + }) + + it('returns a correct result', () => { + expect( + A.differenceWith([{ a: 1 }, { b: 2 }],[{ a: 1 }, { c: 3 }], F.equals), + ).toEqual([{ b: 2 }]) + }) + + it('*', () => { + expect(A.differenceWith([1, 2, 3, 4],[3, 4, 5, 6], F.equals)).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.equals)), + ) + }) + + it('*', () => { + expect(pipe([5, 2, 3, 5, 6], A.differenceWith([5, 2, 3, 1, 5, 4],F.equals))).toEqual([6]) + }) +}) diff --git a/docs/api/generated/_array.mdx b/docs/api/generated/_array.mdx index 5307aa4..1a92b45 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, compareFn: (_1: A, _2: A) => boolean): Array +function differenceWith(ys: Array, compareFn: (_1: A, _2: A) => boolean): (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..2fea940 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: array<'A>, ys: array<'A>, compareFn) => { + let _ys = ys->uniq + xs->uniq->reject(value => _ys->some((. y) => compareFn(value, y))) +} + %comment("Returns union of two arrays.") @gentype let union = (xs, ys) => xs->concat(ys)->uniq diff --git a/src/Array/index.ts b/src/Array/index.ts index add79e0..6264bcb 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, + compareFn: (_1: A, _2: A) => boolean, +): Array + +export declare function differenceWith( + ys: Array, + compareFn: (_1: A, _2: A) => boolean, +): (xs: Array) => Array + /** Returns union of two arrays. */ export declare function union(ys: Array): (xs: Array) => Array From 294ba1945726877337cb623e6cbce33c9636b2c3 Mon Sep 17 00:00:00 2001 From: Minsang Kim Date: Wed, 14 Feb 2024 13:07:42 +0900 Subject: [PATCH 2/2] feat: update compareFn to selectorFn --- __tests__/Array/differenceWith.test.ts | 21 +++++++++++++++------ docs/api/generated/_array.mdx | 4 ++-- src/Array/Array.res | 6 +++--- src/Array/Array.ts | 5 +++++ src/Array/index.ts | 4 ++-- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/__tests__/Array/differenceWith.test.ts b/__tests__/Array/differenceWith.test.ts index 5beed5d..9615881 100644 --- a/__tests__/Array/differenceWith.test.ts +++ b/__tests__/Array/differenceWith.test.ts @@ -1,6 +1,6 @@ import { expectType } from 'ts-expect' -import { A, F, pipe } from '../..' +import { A, D, F, O, flow, pipe } from '../..' type Obj = { readonly a?: number @@ -11,29 +11,38 @@ type Obj = { describe('differenceWith', () => { it('provides correct types', () => { expectType>( - A.differenceWith(['', 'hello', 'world'],[''], F.equals), + A.differenceWith(['', 'hello', 'world'],[''], F.identity), ) }) it('returns a correct result', () => { expect( - A.differenceWith([{ a: 1 }, { b: 2 }],[{ a: 1 }, { c: 3 }], F.equals), + 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.equals)).toEqual([1, 2]) + 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.equals)), + 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.equals))).toEqual([6]) + 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 1a92b45..c4bd42f 100644 --- a/docs/api/generated/_array.mdx +++ b/docs/api/generated/_array.mdx @@ -112,8 +112,8 @@ Returns elements from the first array, not existing in the second array, based o ```ts -function differenceWith(xs: Array, ys: Array, compareFn: (_1: A, _2: A) => boolean): Array -function differenceWith(ys: Array, compareFn: (_1: A, _2: A) => boolean): (xs: Array) => Array +function differenceWith(xs: Array, ys: Array, fn: (x: A) => unknown): Array +function differenceWith(ys: Array, fn: (x: A) => unknown): (xs: Array) => Array ``` ```ts diff --git a/src/Array/Array.res b/src/Array/Array.res index 2fea940..3671a28 100644 --- a/src/Array/Array.res +++ b/src/Array/Array.res @@ -666,9 +666,9 @@ let difference = (xs, ys) => xs->uniq->reject(value => includes(ys, value)) "Returns elements from the first array, not existing in the second array, based on a comparison function." ) @gentype -let differenceWith = (xs: array<'A>, ys: array<'A>, compareFn) => { - let _ys = ys->uniq - xs->uniq->reject(value => _ys->some((. y) => compareFn(value, y))) +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.") 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 6264bcb..3129483 100644 --- a/src/Array/index.ts +++ b/src/Array/index.ts @@ -787,12 +787,12 @@ export declare function difference(xs: Array, ys: Array): Array export declare function differenceWith( xs: Array, ys: Array, - compareFn: (_1: A, _2: A) => boolean, + fn: (x: A) => unknown, ): Array export declare function differenceWith( ys: Array, - compareFn: (_1: A, _2: A) => boolean, + fn: (x: A) => unknown, ): (xs: Array) => Array /** Returns union of two arrays. */