Skip to content

Commit

Permalink
feat(Invert & InvertBy): Added invert and invertBy pipes
Browse files Browse the repository at this point in the history
  • Loading branch information
danrevah committed Dec 10, 2016
1 parent b8ac3c1 commit 4a88c9a
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 3 deletions.
34 changes: 32 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
- [Installation](#installation)
- [Changelog](#changelog)
- [Contributing](#contributing)
- [String](#String)
- [String](#string)
- [repeat](#repeat)
- [scan](#scan)
- [shorten](#shorten)
Expand Down Expand Up @@ -49,6 +49,8 @@
- [values](#values)
- [pairs](#pairs)
- [pick](#pick)
- [invert](#invert)
- [invertby](#invertby)
- [Math](#math)
- [min](#min)
- [max](#max)
Expand All @@ -61,7 +63,7 @@
- [degrees](#degrees)
- [radians](#radians)
- [bytes](#bytes)
- [Boolean](#Boolean)
- [Boolean](#boolean)
- [isNull](#isnull)
- [isDefined](#isdefined)
- [isUndefined](#isundefined)
Expand Down Expand Up @@ -590,6 +592,34 @@ API: `object | pick: [key | string]]`
<p>{{ {foo: 1, bar: 2} | pick: 'foo': 'bar' }}</p> <!-- Output: "{foo: 1, bar: 2}" -->
```
### invert
Returns object with inverted keys and values. in case of equal values, subsequent values overwrite property assignments of previous values.
API: `object | invert`
```html
<p>{{ {foo: 1, bar: 2} | invert }}</p> <!-- Output: "{1: 'foo', 2: 'bar'}" -->
```
### invertBy
Returns object with inverted keys and values. in case of equal values, will add to an array.
API: `object | invertBy: [Function | optional]`
```typescript
this.cb = (value): string => {
return `name_${value}`;
};
```
```html
<p>{{ {foo: 1, bar: 2} | invertBy }}</p> <!-- Output: "{1: ['foo'], 2: ['bar']}" -->
<p>{{ {foo: 1, bar: 2} | invertBy: cb }}</p> <!-- Output: "{name_1: ['foo'], name_2: ['bar']}" -->
<p>{{ {a: 1, b: 2, c: 1, d: 2} | invertBy }}</p> <!-- Output: "{1: ['a', 'c'], 2: ['b', 'd']}" -->
```
## Math
### min
Expand Down
6 changes: 5 additions & 1 deletion src/app/pipes/object/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { KeysPipe } from './keys';
import { ValuesPipe } from './values';
import { PairsPipe } from './pairs';
import { PickPipe } from './pick';
import { InvertPipe } from './invert';
import { InvertByPipe } from './invert-by';
import { NgModule } from '@angular/core';

const OBJECT_PIPES = [
KeysPipe, ValuesPipe, PairsPipe, PickPipe
KeysPipe, ValuesPipe, PairsPipe, PickPipe, InvertPipe, InvertByPipe
];

@NgModule({
Expand All @@ -19,3 +21,5 @@ export * from './keys';
export * from './values';
export * from './pairs';
export * from './pick';
export * from './invert';
export * from './invert-by';
35 changes: 35 additions & 0 deletions src/app/pipes/object/invert-by.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {InvertByPipe} from './invert-by';

describe('InvertBy Pipe', () => {
let pipe: InvertByPipe;

beforeEach(() => {
pipe = new InvertByPipe();
});

it('should keep the element the same way if its not an object', () => {
expect(pipe.transform([1, 2, 3])).toEqual([1, 2, 3]);
expect(pipe.transform([])).toEqual([]);
expect(pipe.transform('foo')).toEqual('foo');
expect(pipe.transform(null)).toEqual(null);
expect(pipe.transform(undefined)).toEqual(undefined);
});

it('should return inverted values / keys object', () => {
expect(pipe.transform({})).toEqual({});
expect(pipe.transform({foo: 'bar'})).toEqual({bar: ['foo']});
expect(pipe.transform({foo: 1, bar: 42})).toEqual({1: ['foo'], 42: ['bar']});

expect(pipe.transform({}, _ => `name_${_}`)).toEqual({});
expect(pipe.transform({foo: 'bar'}, _ => `name_${_}`)).toEqual({name_bar: ['foo']});
expect(pipe.transform({foo: 1, bar: 42}, _ => `name_${_}`)).toEqual({name_1: ['foo'], name_42: ['bar']});
});

it('should return inverted values / keys subsequent values override previous value', () => {
expect(pipe.transform({a: 1, b: 2, c: 1})).toEqual({1: ['a', 'c'], 2: ['b']});
expect(pipe.transform({a: 1, b: 2, c: 1, d: 2, e: 3})).toEqual({1: ['a','c'], 2: ['b','d'], 3: ['e']});

expect(pipe.transform({a: 1, b: 2, c: 1}, _ => `name_${_}`)).toEqual({name_1: ['a', 'c'], name_2: ['b']});
expect(pipe.transform({a: 1, b: 2, c: 1, d: 2, e: 3}, _ => `name_${_}`)).toEqual({name_1: ['a','c'], name_2: ['b','d'], name_3: ['e']});
});
});
20 changes: 20 additions & 0 deletions src/app/pipes/object/invert-by.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {PipeTransform, Pipe} from '@angular/core';
import GeneralHelper from '../helpers/helpers';

@Pipe({name: 'invertBy'})
export class InvertByPipe implements PipeTransform {

transform(obj: any, cb: Function = null): Object {
if (Array.isArray(obj) || !GeneralHelper.isObject(obj)) {
return obj;
}

return Object.keys(obj)
.reduce((o, k) => {
const key = cb ? cb(obj[k]) : obj[k];
return Array.isArray(o[key])
? (o[key].push(k), o)
: Object.assign(o, {[key]: [k]});
}, {});
}
}
30 changes: 30 additions & 0 deletions src/app/pipes/object/invert.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {InvertPipe} from './invert';

describe('Invert Pipe', () => {
let pipe: InvertPipe;

beforeEach(() => {
pipe = new InvertPipe();
});

it('should keep the element the same way if its not an object', () => {
expect(pipe.transform([1, 2, 3])).toEqual([1, 2, 3]);
expect(pipe.transform([])).toEqual([]);
expect(pipe.transform('foo')).toEqual('foo');
expect(pipe.transform(null)).toEqual(null);
expect(pipe.transform(undefined)).toEqual(undefined);
});

it('should return inverted values / keys object', () => {
expect(pipe.transform({})).toEqual({});
expect(pipe.transform({foo: 'bar'})).toEqual({bar: 'foo'});
expect(pipe.transform({foo: 1, bar: 42})).toEqual({1: 'foo', 42: 'bar'});
expect(pipe.transform({foo: [1, 2], bar: 42})).toEqual({'1,2': 'foo', 42: 'bar'});
expect(pipe.transform({foo: {a: 1, b: 2}, bar: 42})).toEqual({'[object Object]': 'foo', 42: 'bar'});
});

it('should return inverted values / keys subsequent values override previous value', () => {
expect(pipe.transform({a: 1, b: 2, c: 1})).toEqual({1: 'c', 2: 'b'});
expect(pipe.transform({a: 1, b: 2, c: 1, d: 2, e: 3})).toEqual({1: 'c', 2: 'd', 3: 'e'});
});
});
15 changes: 15 additions & 0 deletions src/app/pipes/object/invert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {PipeTransform, Pipe} from '@angular/core';
import GeneralHelper from '../helpers/helpers';

@Pipe({name: 'invert'})
export class InvertPipe implements PipeTransform {

transform(obj: any): Object {
if (Array.isArray(obj) || !GeneralHelper.isObject(obj)) {
return obj;
}

return Object.keys(obj)
.reduce((o, k) => Object.assign(o, {[obj[k]]: k}), {});
}
}

0 comments on commit 4a88c9a

Please sign in to comment.