diff --git a/README.md b/README.md index 47710a7d..ff6740b5 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ - [sample](#sample) - [groupBy](#groupby) - [filterBy](#filterby) + - [orderBy](#orderBy) - [Object](#object) - [keys](#keys) - [values](#values) @@ -611,7 +612,7 @@ this.arrayNestedObject = [ ### filterBy -Returns object of grouped by items by discriminator +Returns object array of grouped by items by discriminator **Usage:** `array | filterBy: [prop, nested.prop, ...]: search: [strict | optional]` @@ -638,6 +639,52 @@ this.users = [ ``` +### orderBy + +Returns ordered array by configuration + +**Usage:** `array | orderBy: [prop, nested.prop, array of props, ...]` + +```typescript +const numbers = [2, 1, 3]; + +const obj = [ + {id: 4, name: 'Dave', amount: 2}, + {id: 2, name: 'Michael', amount: 2}, + {id: 3, name: 'Dan', amount: 1}, + {id: 1, name: 'John', amount: 1} +]; + +const deepObj = [ + {id: 1, name: 'John', amount: 1337, deep: {prop: 4}}, + {id: 2, name: 'Michael', amount: 42, deep: {prop: 2}}, + {id: 3, name: 'Dan', amount: 1, deep: {prop: 1}}, + {id: 4, name: 'Dave', amount: 2, deep: {prop: 3}} +]; +``` + +```html + +

{{ numbers | orderBy }}

+

{{ numbers | orderBy: '-' }}

+ + +

{{ deepObj | orderBy: 'amount' }}

+ +

{{ deepObj | orderBy: '-amount' }}

+ + + +

{{ deepObj | orderBy: 'deep.prop' }}

+ +

{{ deepObj | orderBy: '-deep.prop' }}

+ + + +

{{ obj | orderBy: ['amount', 'id'] }}

+ +``` + ## Object ### keys diff --git a/src/app/pipes/array/order-by.spec.ts b/src/app/pipes/array/order-by.spec.ts new file mode 100644 index 00000000..2af4d5a9 --- /dev/null +++ b/src/app/pipes/array/order-by.spec.ts @@ -0,0 +1,128 @@ +import {OrderByPipe} from './order-by'; + +describe('OrderByPipe', () => { + const testArray = [ + {id: 1, name: 'John', amount: 1337}, + {id: 2, name: 'Michael', amount: 42}, + {id: 3, name: 'Dan', amount: 1}, + {id: 4, name: 'Dave', amount: 2} + ]; + + let pipe: OrderByPipe; + + beforeEach(() => { + pipe = new OrderByPipe(); + }); + + it('should not do anything in-case of not an array', () => { + expect(pipe.transform('foo')).toEqual('foo'); + 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 create a new version of the array', () => { + const arr = [3, 2, 1]; + expect(pipe.transform(arr)).toEqual([1, 2, 3]); + expect(arr).toEqual([3, 2, 1]); + }); + + it('should order by value if there is no config', () => { + expect(pipe.transform([3, 2, 1])).toEqual([1, 2, 3]); + expect(pipe.transform(['c', 'b', 'a'])).toEqual(['a', 'b', 'c']); + }); + + it('should order by reverse value if there a stringy value of `-`', () => { + expect(pipe.transform([3, 2, 1], '-')).toEqual([3, 2, 1]); + expect(pipe.transform(['c', 'b', 'a'], '-')).toEqual(['c', 'b', 'a']); + expect(pipe.transform([1, 2, 3], '-')).toEqual([3, 2, 1]); + expect(pipe.transform(['a', 'b', 'c'], '-')).toEqual(['c', 'b', 'a']); + }); + + it('should order by value if there a stringy value of `+`', () => { + expect(pipe.transform([3, 2, 1], '+')).toEqual([1, 2, 3]); + expect(pipe.transform(['c', 'b', 'a'], '+')).toEqual(['a', 'b', 'c']); + }); + + it('should order by property if there a stringy value of `+property` or `property`', () => { + expect(pipe.transform(testArray, 'amount')).toEqual([ + {id: 3, name: 'Dan', amount: 1}, + {id: 4, name: 'Dave', amount: 2}, + {id: 2, name: 'Michael', amount: 42}, + {id: 1, name: 'John', amount: 1337} + ]); + + expect(pipe.transform(testArray, '+amount')).toEqual([ + {id: 3, name: 'Dan', amount: 1}, + {id: 4, name: 'Dave', amount: 2}, + {id: 2, name: 'Michael', amount: 42}, + {id: 1, name: 'John', amount: 1337} + ]); + }); + + it('should reverse order by property if there a stringy value of `-property`', () => { + expect(pipe.transform(testArray, '-amount')).toEqual([ + {id: 1, name: 'John', amount: 1337}, + {id: 2, name: 'Michael', amount: 42}, + {id: 4, name: 'Dave', amount: 2}, + {id: 3, name: 'Dan', amount: 1} + ]); + }); + + it('should reverse order by multiple properties if there an array values', () => { + expect(pipe.transform([ + {id: 4, name: 'Dave', amount: 2}, + {id: 2, name: 'Michael', amount: 2}, + {id: 3, name: 'Dan', amount: 1}, + {id: 1, name: 'John', amount: 1} + ], ['amount', '+id'])).toEqual([ + {id: 1, name: 'John', amount: 1}, + {id: 3, name: 'Dan', amount: 1}, + {id: 2, name: 'Michael', amount: 2}, + {id: 4, name: 'Dave', amount: 2} + ]); + }); + + it('should reverse order by multiple properties if there an array values', () => { + expect(pipe.transform([ + {id: 2, name: 'b', amount: 2}, + {id: 2, name: 'a', amount: 2}, + {id: 1, name: 'd', amount: 1}, + {id: 1, name: 'c', amount: 1} + ], ['amount', '+id', '-name'])).toEqual([ + {id: 1, name: 'd', amount: 1}, + {id: 1, name: 'c', amount: 1}, + {id: 2, name: 'b', amount: 2}, + {id: 2, name: 'a', amount: 2} + ]); + }); + + it('should order by deep property', () => { + expect(pipe.transform([ + {id: 1, name: 'John', amount: 1337, deep: {prop: 4}}, + {id: 2, name: 'Michael', amount: 42, deep: {prop: 2}}, + {id: 3, name: 'Dan', amount: 1, deep: {prop: 1}}, + {id: 4, name: 'Dave', amount: 2, deep: {prop: 3}} + ], ['deep.prop'])).toEqual([ + {id: 3, name: 'Dan', amount: 1, deep: {prop: 1}}, + {id: 2, name: 'Michael', amount: 42, deep: {prop: 2}}, + {id: 4, name: 'Dave', amount: 2, deep: {prop: 3}}, + {id: 1, name: 'John', amount: 1337, deep: {prop: 4}} + ]); + }); + + it('should order by deep property', () => { + expect(pipe.transform([ + {id: 1, name: 'John', amount: 1337, deep: {prop: 4}}, + {id: 2, name: 'Michael', amount: 42, deep: {prop: 2}}, + {id: 3, name: 'Dan', amount: 1, deep: {prop: 1}}, + {id: 4, name: 'Dave', amount: 2, deep: {prop: 3}} + ], ['-deep.prop'])).toEqual([ + {id: 1, name: 'John', amount: 1337, deep: {prop: 4}}, + {id: 4, name: 'Dave', amount: 2, deep: {prop: 3}}, + {id: 2, name: 'Michael', amount: 42, deep: {prop: 2}}, + {id: 3, name: 'Dan', amount: 1, deep: {prop: 1}} + ]); + }); +}); diff --git a/src/app/pipes/array/order-by.ts b/src/app/pipes/array/order-by.ts new file mode 100644 index 00000000..539260f7 --- /dev/null +++ b/src/app/pipes/array/order-by.ts @@ -0,0 +1,59 @@ +import {PipeTransform, Pipe} from '@angular/core'; +import GeneralHelper from '../helpers/helpers'; + +@Pipe({name: 'orderBy'}) +export class OrderByPipe implements PipeTransform { + + transform(arr: any, config?: any): any[] { + if (!Array.isArray(arr)) { + return arr; + } + + const out = [...arr]; + + if (Array.isArray(config)) { + + return out.sort((a, b) => { + let pos; + + for (let i=0, l=config.length; i k ? `_${c.toLowerCase()}` : c.toLowerCase()) + ? text.trim() + .replace(/\s+/g, '') + .replace(/[A-Z]/g, (c, k) => k ? `_${c.toLowerCase()}` : c.toLowerCase()) : text; } }