diff --git a/src/implements/methods.ts b/src/implements/methods.ts index 43d764e..52e6b23 100644 --- a/src/implements/methods.ts +++ b/src/implements/methods.ts @@ -1,14 +1,12 @@ import { IMethods, IIterator } from "../intefaces"; -import { Utils } from '../utils/object'; +import { Utils } from '../utils'; import { WhereClause, SelectClause, SelectManyClause, JoinClause, LeftJoinClause, OrderByClause, OrderByDescendingClause, GroupByClause, GroupJoinClause, FirstClause, LastClause, CountClause, SumClause, AvarageClause, MinClause, MaxClause, SingleClause, TakeClause, SkipWhileClause, - SkipClause, TakeWhileClause, AnyClause, ContainsClause, AllClause + SkipClause, TakeWhileClause, AnyClause, ContainsClause, AllClause, DistinctClause, ConcatClause } from "../methods"; import { Queryable } from './queryable'; -import { DistinctClause } from '../methods/distinct'; -import { ConcatClause } from '../methods/concat'; export class IteratorMethods implements IMethods { diff --git a/src/methods/all.ts b/src/methods/all.ts index b4a6a63..f852e18 100644 --- a/src/methods/all.ts +++ b/src/methods/all.ts @@ -5,7 +5,7 @@ export class AllClause extends BaseIterator implements IIterator { _iterator: (item: T) => boolean; - execute(source: T[] | any[]): T[] | T | any { + execute(source: T[]): boolean { if (!source) return false; else { return (source as T[]).every((x) => { diff --git a/src/methods/any.ts b/src/methods/any.ts index 037e8af..02eb55c 100644 --- a/src/methods/any.ts +++ b/src/methods/any.ts @@ -5,7 +5,7 @@ export class AnyClause extends BaseIterator implements IIterator { _iterator: (item: T) => boolean; - execute(source: T[] | any[]): T[] | T | any { + execute(source: T[]): boolean { if (!source) return false; else { return (source as T[]).some((x) => { diff --git a/src/methods/average.ts b/src/methods/average.ts index 6b41707..8516d05 100644 --- a/src/methods/average.ts +++ b/src/methods/average.ts @@ -6,12 +6,12 @@ export class AvarageClause extends BaseIterator implements IIterator { _iterator: (item: T) => any; - execute(source: any[] | T[]): T[] | T | any { + execute(source: T[]): number { if (!source) return 0; - let _result = this._iterator + let _result = (this._iterator ? new SelectClause(this._iterator).execute(source) as number[] - : source; + : source) as number[]; if (!_result) return 0; if (Number.isNaN(_result[0])) throw new Error("Avarage operator need type of number"); diff --git a/src/methods/contains.ts b/src/methods/contains.ts index d6fc5c8..59ff691 100644 --- a/src/methods/contains.ts +++ b/src/methods/contains.ts @@ -1,5 +1,6 @@ import { IIterator } from "../intefaces/iterator.interface"; import { BaseIterator } from "../implements/baseIterator"; +import { Utils } from '../utils'; export class ContainsClause extends BaseIterator implements IIterator { @@ -11,7 +12,7 @@ export class ContainsClause extends BaseIterator implements IIterator { let _flag = false; for (let i = 0, li = source.length; i < li; i++) { - if (source[i] === this._entity) { + if (Utils.compare(source[i], this._entity)) { _flag = true; break; } diff --git a/src/methods/count.ts b/src/methods/count.ts index afe317e..715439b 100644 --- a/src/methods/count.ts +++ b/src/methods/count.ts @@ -5,13 +5,13 @@ export class CountClause extends BaseIterator implements IIterator { _iterator: (item: T) => boolean; - execute(source: any[] | T[]): T[] | T | any { - if (!source) return source.length; + execute(source: T[]): number { + if (!source) return 0; else if (!this._iterator) return source.length; else { return (source as T[]).filter((x) => { return this._iterator(x); - }).length; + }).length || 0; } } diff --git a/src/methods/first.ts b/src/methods/first.ts index 5762b4a..a75cc22 100644 --- a/src/methods/first.ts +++ b/src/methods/first.ts @@ -5,10 +5,9 @@ export class FirstClause extends BaseIterator implements IIterator { _iterator: (item: T) => boolean; - execute(source: any[] | T[]): T[] | T { - if (!this._iterator) { + execute(source: T[]): T { + if (!this._iterator) return source[0]; - } else { return (source as T[]).filter((x) => { return this._iterator(x); diff --git a/src/methods/groupBy.ts b/src/methods/groupBy.ts index 6bd47a1..e3c9d71 100644 --- a/src/methods/groupBy.ts +++ b/src/methods/groupBy.ts @@ -1,6 +1,7 @@ import { IIterator } from "../intefaces/iterator.interface"; import { SelectClause } from "./select"; import { BaseIterator } from "../implements/baseIterator"; +import { Utils } from '../utils'; export class GroupByClause extends BaseIterator implements IIterator { @@ -13,7 +14,7 @@ export class GroupByClause extends BaseIterator implements IIterator { let _mappingSource = {}; // Object contains all data in array follow by [index] : {object} let _indexes = [] as Array<{ value, index }>; // Make indexes table base on iterator function let _groupByObj = {} // Object contains [groupByValue] : [] - let _distinctGroupByValues = this.distinct + let _distinctGroupByValues = Utils.distinct (new SelectClause(this._iterator).execute(source)); // Make mapping source by indexes @@ -52,10 +53,4 @@ export class GroupByClause extends BaseIterator implements IIterator { super(); this._iterator = func; } - - private distinct(array: any[]) { - return array.filter((val, index, self) => { - return self.indexOf(val) === index; - }).filter(x => x != undefined); - } } \ No newline at end of file diff --git a/src/methods/groupJoin.ts b/src/methods/groupJoin.ts index 1320c99..a455eb4 100644 --- a/src/methods/groupJoin.ts +++ b/src/methods/groupJoin.ts @@ -6,7 +6,7 @@ import { BaseIterator } from "../implements/baseIterator"; export class GroupJoinClause extends BaseIterator implements IIterator { - nextSource: any[] | Promise; + nextSource: any[]; _joinIterator: (aEntity: T, bEntity: S) => boolean; @@ -35,10 +35,4 @@ export class GroupJoinClause extends BaseIterator implements IIterator< this._groupIterator = groupIterator; this.nextSource = anotherSource; } - - private distinct(array: any[]) { - return array.filter((val, index, self) => { - return self.indexOf(val) === index; - }).filter(x => x != undefined); - } } \ No newline at end of file diff --git a/src/methods/index.ts b/src/methods/index.ts index 95a6865..c6162f5 100644 --- a/src/methods/index.ts +++ b/src/methods/index.ts @@ -21,4 +21,6 @@ export * from './sum'; export * from './take'; export * from './takeWhile'; export * from './where'; -export * from './all'; \ No newline at end of file +export * from './all'; +export * from './concat'; +export * from './distinct'; \ No newline at end of file diff --git a/src/methods/join.ts b/src/methods/join.ts index 6bfea68..4d75b4c 100644 --- a/src/methods/join.ts +++ b/src/methods/join.ts @@ -7,7 +7,7 @@ export class JoinClause extends BaseIterator implements IIterator { nextSource: S[] | Promise; - execute(source: any[] | T[]): T[] | any[] { + execute(source: T[]): { x: T, y: S }[] { if (source) { let _result = []; for (let i = 0, li = source.length; i < li; i++) { @@ -24,7 +24,7 @@ export class JoinClause extends BaseIterator implements IIterator { } return _result; } - return source; + return source as any; } constructor(anotherSource: S[] | Promise, func: (item1: T, item2: S) => boolean) { diff --git a/src/methods/last.ts b/src/methods/last.ts index f16a00e..b944daf 100644 --- a/src/methods/last.ts +++ b/src/methods/last.ts @@ -5,10 +5,8 @@ export class LastClause extends BaseIterator implements IIterator { _iterator: (item: T) => boolean; - execute(source: any[] | T[]): T[] | T { - if (!source) { - return source[source.length]; - } + execute(source: T[]): T { + if (!source) return null; else { if (!this._iterator) return source[source.length - 1]; return (source as T[]).filter((x) => { diff --git a/src/methods/leftJoin.ts b/src/methods/leftJoin.ts index f9d0f1b..17b8d3d 100644 --- a/src/methods/leftJoin.ts +++ b/src/methods/leftJoin.ts @@ -5,9 +5,9 @@ export class LeftJoinClause extends BaseIterator implements IIterator boolean; - nextSource: any[] | Promise; + nextSource: S[] | Promise; - execute(source: any[] | T[]): T[] | any[] { + execute(source: T[]): any[] { if (source) { let _result = []; for (let i = 0, li = source.length; i < li; i++) { diff --git a/src/methods/max.ts b/src/methods/max.ts index 3cff5e5..f2d70ba 100644 --- a/src/methods/max.ts +++ b/src/methods/max.ts @@ -6,14 +6,17 @@ export class MaxClause extends BaseIterator implements IIterator { _iterator: (item: T) => any; - execute(source: any[] | T[]): T[] | T | any { + execute(source: T[]): number { if (!source) return 0; - let _result = new SelectClause(this._iterator).execute(source) as number[]; + let _result; + + if (this._iterator) + _result = new SelectClause(this._iterator).execute(source) as number[]; if (!_result) return 0; - if (!Number.isNaN(_result[0])) throw new Error("Sum operator require type of number"); + if (!Number.isNaN(_result[0])) throw new Error("Max operator require type of number"); return Math.max(..._result); } diff --git a/src/methods/min.ts b/src/methods/min.ts index 3b52c83..2976f1e 100644 --- a/src/methods/min.ts +++ b/src/methods/min.ts @@ -6,14 +6,17 @@ export class MinClause extends BaseIterator implements IIterator { _iterator: (item: T) => any; - execute(source: any[] | T[]): T[] | T | any { + execute(source: T[]): number { if (!source) return 0; - let _result = new SelectClause(this._iterator).execute(source) as number[]; + let _result; + + if(this._iterator) + _result = new SelectClause(this._iterator).execute(source) as number[]; if (!_result) return 0; - if (!Number.isNaN(_result[0])) throw new Error("Sum operator require type of number"); + if (!Number.isNaN(_result[0])) throw new Error("Min operator require type of number"); return Math.min(..._result); } diff --git a/src/methods/orderBy.ts b/src/methods/orderBy.ts index b4f736c..32ce19e 100644 --- a/src/methods/orderBy.ts +++ b/src/methods/orderBy.ts @@ -6,7 +6,7 @@ export class OrderByClause extends BaseIterator implements IIterator { _iterator: (item: T) => any; - execute(source: T[]): T[] | any[] { + execute(source: T[]): T[] { if (!source) return null; diff --git a/src/methods/orderByDescending.ts b/src/methods/orderByDescending.ts index 54b4e03..0357878 100644 --- a/src/methods/orderByDescending.ts +++ b/src/methods/orderByDescending.ts @@ -6,7 +6,7 @@ export class OrderByDescendingClause extends BaseIterator implements IIter _iterator: (item: T) => any; - execute(source: T[]): T[] | any[] { + execute(source: T[]): T[] { if (!source) return null; diff --git a/src/methods/select.ts b/src/methods/select.ts index 37fdd98..f72ca88 100644 --- a/src/methods/select.ts +++ b/src/methods/select.ts @@ -5,7 +5,7 @@ export class SelectClause extends BaseIterator implements IIterator { _iterator: (item: T) => boolean; - execute(source: any[] | T[]): T[] | any[] { + execute(source: T[]): any[]{ if (source) { return (source as T[]).map(x => (this._iterator(x))); } diff --git a/src/methods/selectMany.ts b/src/methods/selectMany.ts index 1a52be9..defaa05 100644 --- a/src/methods/selectMany.ts +++ b/src/methods/selectMany.ts @@ -6,7 +6,7 @@ export class SelectManyClause extends BaseIterator implements IIterator _iterator: (item: T, index?: number) => any; - execute(source: any[] | T[]): T[] | any[] { + execute(source: T[]): any[] { if (!source) return null; let _result = new SelectClause(this._iterator).execute(source); diff --git a/src/methods/single.ts b/src/methods/single.ts index eb75a96..6041446 100644 --- a/src/methods/single.ts +++ b/src/methods/single.ts @@ -1,25 +1,20 @@ import { IIterator } from "../intefaces/iterator.interface"; import { WhereClause } from "./where"; import { BaseIterator } from "../implements/baseIterator"; +import { Utils } from '../utils'; export class SingleClause extends BaseIterator implements IIterator { _iterator: (item: T) => boolean; - execute(source: any[] | T[]): T { - if (!this._iterator) { - return this.getSingle(source); - } - else { - let _result = new WhereClause(this._iterator).execute(source); - return this.getSingle(_result); - } - } + execute(source: T[]): T { + + let _result = source; + + if (this._iterator) + _result = new WhereClause(this._iterator).execute(_result); - private getSingle(src: any[] | T[]): T | any { - if (src.length > 1) throw new Error("The collection does not contain exactly one element"); - else if (src.length === 1) - return src[0]; + return Utils.getSingle(_result); } constructor(func?: (item: T) => boolean) { diff --git a/src/methods/skip.ts b/src/methods/skip.ts index 0262ac0..2c36411 100644 --- a/src/methods/skip.ts +++ b/src/methods/skip.ts @@ -5,9 +5,9 @@ export class SkipClause extends BaseIterator implements IIterator { _iterator: number; - execute(source: any[] | T[]): T[] | any[] { + execute(source: T[]): T[]{ if (source) { - return (source as T[]).slice(this._iterator); + return source.slice(this._iterator); } return source; } diff --git a/src/methods/skipWhile.ts b/src/methods/skipWhile.ts index e38f733..827b5d5 100644 --- a/src/methods/skipWhile.ts +++ b/src/methods/skipWhile.ts @@ -6,15 +6,15 @@ export class SkipWhileClause extends BaseIterator implements IIterator _iterator: (item: T) => boolean; - execute(source: any[] | T[]): T[] | any[] { + execute(source: T[]): T[]{ if (source) { let _skipCount = 0; - for (let i = 0; i < (source as T[]).length; i++) { + for (let i = 0; i < source.length; i++) { const _item = source[i]; if (this._iterator(_item)) break; _skipCount += 1; } - return new SkipClause(_skipCount).execute(source); + return new SkipClause(_skipCount).execute(source); } return null; } diff --git a/src/methods/sum.ts b/src/methods/sum.ts index dca6131..7b850c0 100644 --- a/src/methods/sum.ts +++ b/src/methods/sum.ts @@ -6,10 +6,13 @@ export class SumClause extends BaseIterator implements IIterator { _iterator: (item: T) => any; - execute(source: any[] | T[]): T[] | T | any { + execute(source: T[]): number { if (!source) return 0; - let _result = new SelectClause(this._iterator).execute(source) as number[]; + let _result; + + if (this._iterator) + _result = new SelectClause(this._iterator).execute(source) as number[]; if (!_result) return 0; diff --git a/src/methods/take.ts b/src/methods/take.ts index 6fd20cf..3113b49 100644 --- a/src/methods/take.ts +++ b/src/methods/take.ts @@ -5,7 +5,7 @@ export class TakeClause extends BaseIterator implements IIterator { _iterator: number; - execute(source: any[] | T[]): T[] | any[] { + execute(source: T[]): T[]{ if (source) { return (source as T[]).slice(0, this._iterator); } diff --git a/src/methods/takeWhile.ts b/src/methods/takeWhile.ts index 9b444f4..b9de863 100644 --- a/src/methods/takeWhile.ts +++ b/src/methods/takeWhile.ts @@ -6,7 +6,7 @@ export class TakeWhileClause extends BaseIterator implements IIterator _iterator: (item: T) => boolean; - execute(source: any[] | T[]): T[] | any[] { + execute(source: T[]): T[]{ if (source) { let _takeCount = 0; for (let i = 0; i < (source as T[]).length; i++) { @@ -14,7 +14,7 @@ export class TakeWhileClause extends BaseIterator implements IIterator if (this._iterator(_item)) break; _takeCount += 1; } - return new TakeClause(_takeCount).execute(source); + return new TakeClause(_takeCount).execute(source); } return null; } diff --git a/src/methods/where.ts b/src/methods/where.ts index 83317c2..ad18e01 100644 --- a/src/methods/where.ts +++ b/src/methods/where.ts @@ -5,7 +5,7 @@ export class WhereClause extends BaseIterator implements IIterator { _iterator: (item: T) => boolean; - execute(source: any[] | T[]): T[] | any[] { + execute(source: T[]): T[]{ if (source) { return (source as T[]).filter((x) => { return this._iterator(x); diff --git a/src/utils/index.ts b/src/utils/index.ts index 78e028b..5652708 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1 +1 @@ -export * from './object'; \ No newline at end of file +export * from './utility'; \ No newline at end of file diff --git a/src/utils/object.ts b/src/utils/object.ts deleted file mode 100644 index 358353d..0000000 --- a/src/utils/object.ts +++ /dev/null @@ -1,11 +0,0 @@ -export class Utils { - public static isPromise(obj) { - return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'; - } - - public static distinct(array: any[]) { - return array.filter((val, index, self) => { - return self.indexOf(val) === index; - }).filter(x => x != undefined); - } -} \ No newline at end of file diff --git a/src/utils/utility.ts b/src/utils/utility.ts new file mode 100644 index 0000000..9ee9ef4 --- /dev/null +++ b/src/utils/utility.ts @@ -0,0 +1,53 @@ +export class Utils { + public static isPromise(obj): boolean { + return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'; + } + + public static distinct(array: any[]): any[] { + return array.filter((val, index, self) => { + return self.indexOf(val) === index; + }).filter(x => x != undefined); + } + + public static getSingle(src: any[]): any { + if (src.length > 1) throw new Error("The collection does not contain exactly one element"); + else if (src.length === 1) + return src[0]; + } + + public static compare(obj: any, obj2: any): boolean { + if (obj === obj2) return true; + + const objIsArray = Array.isArray(obj); + const obj2IsArray = Array.isArray(obj2); + + if (objIsArray && obj2IsArray) { + + if ((obj as any[]).length !== (obj2 as any[]).length) return false; + + for (let i = 0, li = obj.length; i < li; i++) { + const result = this.compare(obj[i], obj2[i]); + if (!result) return false; + } + + return true; + + } else { + const objIsObject = typeof obj === 'object'; + const obj2IsObject = typeof obj2 === 'object'; + + if (objIsObject && obj2IsObject) { + const props = Object.keys(objIsObject); + + for (let i = 0, li = props.length; i < li; i++) { + const result = this.compare(objIsObject[props[i]], obj2IsObject[props[i]]); + if (!result) return false; + } + + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 93ca402..89c1bee 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,7 +23,7 @@ ] }, "baseUrl": "./", - "declaration": true, + // "declaration": true, }, "exclude": [ "demo",