diff --git a/src/app/pipes/array/groupBy.spec.ts b/src/app/pipes/array/groupBy.spec.ts new file mode 100644 index 00000000..3616f220 --- /dev/null +++ b/src/app/pipes/array/groupBy.spec.ts @@ -0,0 +1,61 @@ +import { GroupByPipe } from './groupBy'; + +describe('Pipe: GroupBy', () => { + it('create an instance', () => { + let pipe = new GroupByPipe(); + expect(pipe).toBeTruthy(); + }); + +}); +describe('GroupByPipe', () => { + let pipe: GroupByPipe; + + beforeEach(() => { + pipe = new GroupByPipe(); + }); + + it('should not change anything if not 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('group on discriminator', () => { + let arrayWithDiscriminator = [ + { + key: 'value0' + }, + { + key: 'value1' + }, + { + key: 'value0' + }, + { + key: 'value1' + } + ]; + let result = pipe.transform(arrayWithDiscriminator, 'key'); + expect(result).toEqual([ [ 'value0', [ { key: 'value0' }, { key: 'value0' }] ], [ 'value1', [ { key: 'value1' }, { key: 'value1' }] ] ]); + }); + it('allow function to be used as discriminator', () => { + let arrayWithDiscriminator = [ + { + key: 'value0' + }, + { + key: 'value1' + }, + { + key: 'value0' + }, + { + key: 'value1' + } + ]; + let result = pipe.transform(arrayWithDiscriminator, (instance: any) => { return instance[ 'key' ] }); + expect(result).toEqual([ [ 'value0', [ { key: 'value0' }, { key: 'value0' }] ], [ 'value1', [ { key: 'value1' }, { key: 'value1' }] ] ]); + }); +}); diff --git a/src/app/pipes/array/groupBy.ts b/src/app/pipes/array/groupBy.ts new file mode 100644 index 00000000..99ca52f6 --- /dev/null +++ b/src/app/pipes/array/groupBy.ts @@ -0,0 +1,23 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'groupBy' +}) +export class GroupByPipe implements PipeTransform { + groupBy = (list: any[], discriminator: Function | string) => { + let map = list.reduce((acc, payload, i) => { + let key = discriminator instanceof Function ? discriminator(payload) : payload[ discriminator ]; + return Object.assign({}, acc, { + [ key ]: acc[ key ] instanceof Array ? acc[ key ].concat([ payload ]) : [ payload ] + }); + }, {}); + return Object.keys(map).map((key: string) => [ key, map[ key ] ]); + } + transform(arr: any, ...args: any[]): any { + if (!Array.isArray(arr)) { + return arr; + } + return this.groupBy(arr, args[ 0 ]); + } + +} \ No newline at end of file diff --git a/src/app/pipes/array/index.ts b/src/app/pipes/array/index.ts index 02aa27fc..6fc10c08 100644 --- a/src/app/pipes/array/index.ts +++ b/src/app/pipes/array/index.ts @@ -1,32 +1,33 @@ -import {DiffPipe} from './diff'; -import {InitialPipe} from './initial'; -import {FlattenPipe} from './flatten'; -import {IntersectionPipe} from './intersection'; -import {ReversePipe} from './reverse'; -import {TailPipe} from './tail'; -import {TrurthifyPipe} from './truthify'; -import {UnionPipe} from './union'; -import {UniquePipe} from './unique'; -import {WithoutPipe} from './without'; -import {PluckPipe} from './pluck'; -import {ShufflePipe} from './shuffle'; -import {EveryPipe} from './every'; -import {SomePipe} from './some'; -import {SamplePipe} from './sample'; -import {NgModule} from '@angular/core'; +import { DiffPipe } from './diff'; +import { InitialPipe } from './initial'; +import { FlattenPipe } from './flatten'; +import { IntersectionPipe } from './intersection'; +import { ReversePipe } from './reverse'; +import { TailPipe } from './tail'; +import { TrurthifyPipe } from './truthify'; +import { UnionPipe } from './union'; +import { UniquePipe } from './unique'; +import { WithoutPipe } from './without'; +import { PluckPipe } from './pluck'; +import { ShufflePipe } from './shuffle'; +import { EveryPipe } from './every'; +import { SomePipe } from './some'; +import { SamplePipe } from './sample'; +import { GroupByPipe } from './groupBy'; +import { NgModule } from '@angular/core'; const ARRAY_PIPES = [ DiffPipe, FlattenPipe, InitialPipe, IntersectionPipe, ReversePipe, TailPipe, TrurthifyPipe, UnionPipe, UniquePipe, WithoutPipe, PluckPipe, ShufflePipe, - EveryPipe, SomePipe, SamplePipe + EveryPipe, SomePipe, SamplePipe, GroupByPipe ]; @NgModule({ - declarations: [...ARRAY_PIPES], + declarations: [ ...ARRAY_PIPES ], imports: [], - exports: [...ARRAY_PIPES] + exports: [ ...ARRAY_PIPES ] }) -export class NgArrayPipesModule {} +export class NgArrayPipesModule { } export * from './diff'; export * from './initial'; @@ -43,3 +44,4 @@ export * from './shuffle'; export * from './every'; export * from './some'; export * from './sample'; +export * from './groupBy';