From 88ef0bdd0766ac8ef7e88d82e1067bc1191984a6 Mon Sep 17 00:00:00 2001 From: Nicolas Takashi Date: Mon, 26 Dec 2016 16:42:27 -0200 Subject: [PATCH] Added Take, TakeWhile and ToLookup feature --- boolean | 0 src/lib.es6.d.ts | 5 +- src/linq-to-type.ts | 26 ++++++++- test/linq-to-type.spec.ts | 118 +++++++++++++++++++++++++++++++++++++- 4 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 boolean diff --git a/boolean b/boolean new file mode 100644 index 0000000..e69de29 diff --git a/src/lib.es6.d.ts b/src/lib.es6.d.ts index d7686d1..3f9eb61 100644 --- a/src/lib.es6.d.ts +++ b/src/lib.es6.d.ts @@ -29,5 +29,8 @@ interface Array { zip(second: Array, expression: (a: T, b: TSecond) => TResult): Array; defaultIfEmpty(defaultValue?: T): Array; intersect(source: Array): Array | TypeError; - groupJoin(inner: Array, outerKeySelector: (k: T) => any, innerKeySelector: (k: U) => any, resultSelector: (first: T, second: Array) => any): Array | TypeError + groupJoin(inner: Array, outerKeySelector: (k: T) => any, innerKeySelector: (k: U) => any, resultSelector: (first: T, second: Array) => any): Array | TypeError; + take(count: number): Array | TypeError; + takeWhile(predicate: (value?: T, index?: number, source?: Array) => boolean): Array | TypeError; + toLookup(keySelector: (key: T) => any, elementSelector: (element: T) => any): any | TypeError; } \ No newline at end of file diff --git a/src/linq-to-type.ts b/src/linq-to-type.ts index f2706aa..727b2c1 100644 --- a/src/linq-to-type.ts +++ b/src/linq-to-type.ts @@ -157,4 +157,28 @@ Array.prototype.groupJoin = function (inner, outerKeySelector, innerKeySelector, return this.select((x, y) => resultSelector(x, inner.where(a => outerKeySelector(x) === innerKeySelector(a)))); } throw new TypeError("outer or inner or outerKeySelector or innerKeySelector or resultSelector is null.") -} \ No newline at end of file +} + +Array.prototype.take = function (count) { + if (this.any()) { + return this.slice(0, Math.max(0, count)); + } + + throw new TypeError("source is null") +} + +Array.prototype.takeWhile = function (predicate) { + if (this.any() && predicate !== undefined) { + return this.take(this.aggregate((x, y) => predicate(this.elementAt(x)) ? ++x : x, 0)) + } + + throw new TypeError("source or predicate is null") +} + +Array.prototype.toLookup = function (keySelector, elementSelector) { + if (this.any() && keySelector !== undefined) { + return this.groupBy(keySelector, elementSelector); + } + + throw new TypeError("source or keySelector is null"); +} \ No newline at end of file diff --git a/test/linq-to-type.spec.ts b/test/linq-to-type.spec.ts index 0051ceb..d26bb65 100644 --- a/test/linq-to-type.spec.ts +++ b/test/linq-to-type.spec.ts @@ -545,4 +545,120 @@ describe('GroupJoin test', () => { }) }) }) -}) \ No newline at end of file +}) + +describe('Take test', () => { + describe('Given an array', () => { + describe('and calls Take', () => { + it('should return 1 item from array', () => { + let result = items.take(1) + expect(result.toString()).to.be.eq('1'); + }) + + it('should throws an exception if collection is empty', () => { + let items = [] + expect(() => items.take(1)).to.throws(TypeError, 'source is null') + }) + }) + }) +}) + +describe('TakeWhile test', () => { + describe('Given an array', () => { + describe('and calls TakeWhile', () => { + it('should return fruits that is not orange', () => { + let fruits = ["apple", "banana", "mango", "orange", "passionfruit", "grape"] + let result = fruits.takeWhile(fruit => fruit !== 'orange') + expect(result.toString()).to.be.eq('apple,banana,mango') + }) + + it('should throws an exception if collection is empty', () => { + let fruits = [] + expect(() => fruits.takeWhile(fruit => fruit !== 'orange')).to.throws(TypeError, 'source or predicate is null') + }) + + it('should throws an exception if predicate is empty', () => { + let fruits = ["apple", "banana", "mango", "orange", "passionfruit", "grape"] + expect(() => fruits.takeWhile(undefined)).to.throws(TypeError, 'source or predicate is null') + }) + + }) + }) +}) + +describe('TakeWhile test', () => { + describe('Given an array', () => { + interface IPackage { + Company: string; + Weight: number; + TrackingNumber: number; + }; + + class Package { + public Company: string; + public Weight: number; + public TrackingNumber: number; + + constructor(p: IPackage) { + this.Company = p.Company; + this.Weight = p.Weight; + this.TrackingNumber = p.TrackingNumber; + } + } + + const packages = new Array( + new Package({ + Company: 'Coho Vineyard', + TrackingNumber: 89453312, Weight: 25.2 + }), + new Package({ + Company: 'Lucerne Publishing', + TrackingNumber: 89112755, Weight: 18.7 + }), + new Package({ + Company: 'Wingtip Toys', + TrackingNumber: 299456122, Weight: 6.0 + }), + new Package({ + Company: 'Contoso Pharmaceuticals', + TrackingNumber: 670053128, Weight: 9.3 + }), + new Package({ + Company: 'Wide World Importers', + TrackingNumber: 4665518773, Weight: 33.8 + }) + ); + + const result = { + 'C': [ + 'Coho Vineyard 89453312', + 'Contoso Pharmaceuticals 670053128' + ], + 'L': [ + 'Lucerne Publishing 89112755' + ], + 'W': [ + 'Wingtip Toys 299456122', + 'Wide World Importers 4665518773' + ], + }; + + describe('and calls TakeWhile', () => { + it('should return fruits that is not orange', () => { + let lookup = packages.toLookup(p => p.Company.substring(0, 1), p => p.Company + ' ' + p.TrackingNumber); + expect(JSON.stringify(lookup)).to.be.eq(JSON.stringify(result)) + }) + + it('should throws an exception if collection is empty', () => { + let packages = []; + expect(() => packages.toLookup(p => p.Company.substring(0, 1), p => p.Company + ' ' + p.TrackingNumber)).to.throws(TypeError, 'source or keySelector is null') + }) + + it('should throws an exception if predicate is empty', () => { + expect(() => packages.toLookup(undefined, undefined)).to.throws(TypeError, 'source or keySelector is null') + }) + + }) + }) +}) +