From 351601c3565712b4c88edb52bbe6a718dadab68b Mon Sep 17 00:00:00 2001 From: casualjsenthusiast Date: Fri, 24 Feb 2023 00:19:00 +0530 Subject: [PATCH 1/2] Implement a TakePipe functionality for arrays --- README.md | 18 ++++++ src/ng-pipes/pipes/array/index.ts | 5 +- src/ng-pipes/pipes/array/take.spec.ts | 82 +++++++++++++++++++++++++++ src/ng-pipes/pipes/array/take.ts | 28 +++++++++ 4 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 src/ng-pipes/pipes/array/take.spec.ts create mode 100644 src/ng-pipes/pipes/array/take.ts diff --git a/README.md b/README.md index 31344c72..a48af8d9 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ - [orderByImpure](#orderbyimpure) - [chunk](#chunk) - [fromPairs](#fromPairs) + - [take](#take) - [Object](#object) - [keys](#keys) - [values](#values) @@ -849,6 +850,23 @@ Returns object of an array of key value pairs

{{ [['foo', [1, 2]], ['bar', [3, 4]]] | fromPairs }}

``` +### take +Returns a slice of an array or of a string with n number of elements specified using `count`, +either from the beginning or from the end. + +**Usage:** `array | take: [from:'start'|'end'|default='start']:[count:number|default = 1]` + +```html +

{{ [1, 2, 3, 4, 5] | take }}

+

{{ [1, 2, 3, 4, 5] | take:'end':2 }}

+

{{ "Angular is awesome" | take:'start':7 }}

+``` + +```typescript +this.topTwoFrameworks = this.takePipe.transform(['React', 'Angular', 'Next', 'Vue', 'Svelte']); +console.log(this.topTwoFrameworks) // Returns: ['React', 'Angular'] +``` + ## Object ### keys diff --git a/src/ng-pipes/pipes/array/index.ts b/src/ng-pipes/pipes/array/index.ts index 6c71f01f..26929a72 100644 --- a/src/ng-pipes/pipes/array/index.ts +++ b/src/ng-pipes/pipes/array/index.ts @@ -23,6 +23,7 @@ import { OrderByImpurePipe } from './order-by-impure'; import { RangePipe } from './range'; import { ChunkPipe } from './chunk'; import { FromPairsPipe } from './from-pairs'; +import { TakePipe } from './take'; const ARRAY_PIPES = [ DiffPipe, @@ -48,7 +49,8 @@ const ARRAY_PIPES = [ OrderByImpurePipe, RangePipe, ChunkPipe, - FromPairsPipe + FromPairsPipe, + TakePipe, ]; @NgModule({ @@ -82,3 +84,4 @@ export { OrderByImpurePipe } from './order-by-impure'; export { RangePipe } from './range'; export { ChunkPipe } from './chunk'; export { FromPairsPipe } from './from-pairs'; +export { TakePipe } from './take'; diff --git a/src/ng-pipes/pipes/array/take.spec.ts b/src/ng-pipes/pipes/array/take.spec.ts new file mode 100644 index 00000000..014da854 --- /dev/null +++ b/src/ng-pipes/pipes/array/take.spec.ts @@ -0,0 +1,82 @@ +import { TakePipe } from './take'; + +describe('TakePipe', () => { + let pipe: TakePipe; + + beforeEach(() => { + pipe = new TakePipe(); + }); + + it('should not do anything when not an array or string', () => { + expect(pipe.transform(null)).toEqual(null); + expect(pipe.transform(undefined)).toEqual(undefined); + expect(pipe.transform(42)).toEqual(42); + expect(pipe.transform({ foo: 1, bar: 2 })).toEqual({ foo: 1, bar: 2 }); + }); + + it('should return a slice of array from start for a given count', () => { + const array = [1, 2, 3, 4, 5]; + const result = pipe.transform(array, 'start', 3); + expect(result).toEqual([1, 2, 3]); + }); + + it('should return a slice of array from end for a given count', () => { + const array = [1, 2, 3, 4, 5]; + const result = pipe.transform(array, 'end', 2); + expect(result).toEqual([4, 5]); + }); + + it('should return a slice of a string from start for a given count', () => { + const str = 'Angular is awesome!'; + const result = pipe.transform(str, 'start', 7); + expect(result).toEqual('Angular'); + }); + + it('should return a slice of a string from end for a given count', () => { + const str = 'Angular is awesome!'; + const result = pipe.transform(str, 'end', 8); + expect(result).toEqual('awesome!'); + }); + + it('should not modify original array', () => { + const target = [1, 2, 3]; + pipe.transform(target); + expect(target).toEqual([1, 2, 3]); + }); + + it('should return the array as-is if the count is greater than the array length', () => { + const array = [1, 2, 3, 4, 5]; + const result = pipe.transform(array, 'start', 10); + expect(result).toEqual([1, 2, 3, 4, 5]); + }); + + it('should return a slice of an array from start even for a negative value of count', () => { + const array = [1, 2, 3, 4, 5]; + const result = pipe.transform(array, 'start', -2); + expect(result).toEqual([1, 2]); + }); + + it('should return a slice of a string from start even for a negative value of count', () => { + const str = 'Angular is awesome!'; + const result = pipe.transform(str, 'start', -2); + expect(result).toEqual('An'); + }); + + it('should return only the first element in the array with default parameters', () => { + const array = ['Angular', 'is', 'awesome', '!']; + const result = pipe.transform(array); + expect(result).toEqual(['Angular']); + }); + + it('should return an empty array for a count of 0 and a `from` value of tart', () => { + const array = [1, 2, 3, 4, 5]; + const result = pipe.transform(array, 'start', 0); + expect(result).toEqual([]); + }); + + it('should return an empty array for a count of 0 and a `from` value of end', () => { + const array = [1, 2, 3, 4, 5]; + const result = pipe.transform(array, 'end', 0); + expect(result).toEqual([]); + }); +}); diff --git a/src/ng-pipes/pipes/array/take.ts b/src/ng-pipes/pipes/array/take.ts new file mode 100644 index 00000000..eabf21e4 --- /dev/null +++ b/src/ng-pipes/pipes/array/take.ts @@ -0,0 +1,28 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { isString } from '../helpers/helpers'; + +@Pipe({ name: 'take' }) +export class TakePipe implements PipeTransform { + transform(input: any, from: 'start' | 'end' = 'start', count: number = 1): any { + const isInputString = isString(input); + if (isInputString) { + input = input.split(''); + } + + let transformedArray = []; + const isArray = Array.isArray(input); + + if (isArray) { + count = Math.min(input.length, Math.abs(count)); + if (count === 0) { + transformedArray = []; + } else { + transformedArray = from === 'start' ? input.slice(0, Math.abs(count)) : input.slice(count * -1); + } + } else { + transformedArray = input; + } + + return isInputString ? transformedArray.join('') : transformedArray; + } +} From ab7592b444610f019c7aa4a893e94190bc79d444 Mon Sep 17 00:00:00 2001 From: casualjsenthusiast Date: Fri, 24 Feb 2023 00:40:13 +0530 Subject: [PATCH 2/2] Fix incorrect usage example of takePipe in Readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a48af8d9..a3442815 100644 --- a/README.md +++ b/README.md @@ -863,7 +863,7 @@ either from the beginning or from the end. ``` ```typescript -this.topTwoFrameworks = this.takePipe.transform(['React', 'Angular', 'Next', 'Vue', 'Svelte']); +this.topTwoFrameworks = this.takePipe.transform(['React', 'Angular', 'Next', 'Vue', 'Svelte'], 'start', 2); console.log(this.topTwoFrameworks) // Returns: ['React', 'Angular'] ```