diff --git a/README.md b/README.md index 0bdfab0..7cd5d17 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ You can find the documentations in the [`docs`](./docs) folder or on [`GitBook`] - [`union`](./docs/array.md#union) - [`range`](./docs/array.md#range) - [`map`](./docs/array.md#map) +- [`merge`](./docs/array.md#merge) - [`pluck`](./docs/array.md#pluck) - [`where`](./docs/array.md#where) - [`firstOrDefault`](./docs/array.md#firstordefault) diff --git a/docs/array.md b/docs/array.md index 32a6755..c58e833 100644 --- a/docs/array.md +++ b/docs/array.md @@ -12,6 +12,7 @@ - [`union`](#union) - [`range`](#range) - [`map`](#map) +- [`merge`](#merge) - [`pluck`](#pluck) - [`where`](#where) - [`firstOrDefault`](#firstordefault) @@ -282,6 +283,29 @@ addOne (item) { ``` +#### merge + +Returns the merge of two collection, works with deep equal. + +##### File + +```typescript +import { NgMergePipeModule } from 'angular-pipes'; +``` + +##### Usage + +```html +{{ [1, 2, 3] | union: [1, 2] }} + +{{ [1, 2] | union: [3, 4] }} + +{{ [{ a: 1 }, { a: 2 }] | union: [{ a: 1 }, { a: 3 }] }} + +{{ [{ a: 1 }, { a: 2 }] | deep | union: [{ a: 1 }, { a: 3 }] }} + +``` + #### pluck Returns an array of the given property of the object in the array. diff --git a/src/array/merge.pipe.spec.ts b/src/array/merge.pipe.spec.ts new file mode 100644 index 0000000..acf211a --- /dev/null +++ b/src/array/merge.pipe.spec.ts @@ -0,0 +1,66 @@ +import { UnionPipe } from './union.pipe'; +import { DeepPipe } from './deep.pipe'; +import {MergePipe} from "./merge.pipe"; + +describe('MergePipe', () => { + let pipe: MergePipe; + let deepPipe: DeepPipe; + + beforeEach(() => { + pipe = new MergePipe(); + deepPipe = new DeepPipe(); + }); + + it('Should return the merge', () => { + const a = [1, 1, 1, 2, 3, 3, 4, 5]; + const b = [1, 2]; + const result = pipe.transform(a, b); + expect(result).toEqual([1, 1, 1, 2, 3, 3, 4, 5, 1, 2]); + expect(a).toEqual([1, 1, 1, 2, 3, 3, 4, 5]); // Check integrity + expect(b).toEqual([1, 2]); // Check integrity + }); + + it('Should return the union #2', () => { + const result = pipe.transform([1, 2], [3, 4]); + expect(result).toEqual([1, 2, 3, 4]); + }); + + it('Should merge with null value', () => { + const result = pipe.transform([1, 2], null); + expect(result).toEqual([1, 2]); + }); + + it('Should merge on null value', () => { + const result = pipe.transform(null, [1, 2]); + expect(result).toEqual([1, 2]); + }); + + it('Should merge null values', () => { + const result = pipe.transform(null, null); + expect(result).toEqual([]); + }) + + it('Should return an empty array', () => { + expect(pipe.transform('a')).toEqual([]); + expect(pipe.transform([], 'a')).toEqual([]); + expect(pipe.transform(deepPipe.transform({ a: 1 }), [])).toEqual([]); + }); + + it('Should return the union with no deep equal', () => { + const collection = [{ a: 1, b: { c: 2 } }, { a: 2, b: { c: 3 } }, { a: 2, b: { c: 3 } }, { a: 1, b: { c: 2 } }]; + + const collection2 = [{ a: 1, b: { c: 2 } }]; + + expect(pipe.transform(collection, collection2)).toEqual(collection.concat(collection2)); + }); + + it('Should return union with deep equal', () => { + const collection = [{ a: 1, b: { c: 2 } }, { a: 2, b: { c: 3 } }, { a: 2, b: { c: 3 } }, { a: 1, b: { c: 2 } }]; + + const collection2 = [{ a: 1, b: { c: 2 } }, { a: 2, b: { c: 3 } }, { a: 3, b: { c: 2 } }]; + + const deep = deepPipe.transform(collection); + + expect(pipe.transform(deep, collection2)).toEqual(collection.concat(collection2)); + }); +}); diff --git a/src/array/merge.pipe.ts b/src/array/merge.pipe.ts new file mode 100644 index 0000000..bee3865 --- /dev/null +++ b/src/array/merge.pipe.ts @@ -0,0 +1,36 @@ +import { Pipe, PipeTransform, NgModule } from '@angular/core'; +import { isArray, isDeepObject, unwrapDeep } from '../utils/utils'; + +@Pipe({ + name: 'merge', +}) +export class MergePipe implements PipeTransform { + transform(a?: any, b?: any): any { + a = a === null ? [] : a; + b = b === null ? [] : b; + if ((!isArray(a) && !isDeepObject(a)) || !isArray(b)) { + return []; + } + + if (isDeepObject(a)) { + const unwrapped = unwrapDeep(a); + if (!isArray(unwrapped)) { + return []; + } + + return [] + .concat(unwrapped) + .concat(b); + } + + return [] + .concat(a) + .concat(b); + } +} + +@NgModule({ + declarations: [MergePipe], + exports: [MergePipe], +}) +export class NgMergePipeModule {}