export class List extends Array { /** 返回符合条件的第一个元素 */ first(fn: (item: Item) => boolean): Item { if (this.length == 0) return null for (const item of this) { if (fn(item)) return item } return null } /** 返回符合条件的最后一元素 */ last(fn: (t: Item) => boolean): Item { if (this.length == 0) return null for (let i = this.length - 1; i >= 0; i--) { if (fn(this[i])) return this[i] } return null } /** 最大值 */ max(fn: (item: Item) => T): T { let maxV: T for (const i of this) { let v = fn(i) if (maxV == null) { maxV = fn(i) } else { if (v > maxV) { maxV = v } } } return maxV } /** 最小值 */ min(fn: (item: Item) => T): T { let minV: T for (const i of this) { let v = fn(i) if (minV == null) { minV = fn(i) } else { if (v < minV) { minV = v } } } return minV } /** 累加 */ sum(fn: (item: Item) => number): number { let v: number = 0 for (const t of this) { v = v + fn(t) } return v } /** 平均值 */ avg(fn: (item: Item) => number): number { if (this.length == 0) return 0 let sum = this.sum(fn) return sum / this.length } /** 满足条件的元素数量 */ count(fn: (item: Item) => number): number { if (this.length == 0) return 0 let c = 0 for (const item of this) { if (fn(item)) c = c + 1 } return c } FindMax(fn: (item: Item) => T): Item { return this.reduce((a: Item, b: Item): Item => fn(a) > fn(b) ? a : b) } } export class ArrayExt { /** 返回满足条件的元素数量 */ static count(list: Item[], fn: (item: Item) => boolean): number { if (list.length == 0) return 0 let c = 0 for (const item of list) { if (fn(item)) c = c + 1 } return c } /** 移除 */ static remove(list: Item[], obj: Item) { let index = list.findIndex(t => t == obj) if (index == -1) return list.splice(index, 1) } /** 返回符合条件的第一个元素 */ static first(list: Item[], fn: (item: Item) => boolean, orderFn1: (item: Item) => number = null, orderFn2: (item: Item) => number = null): Item { if (list.length == 0) return null if (orderFn1 == null) { for (const item of list) { if (fn(item)) return item } return null } let minValue1: number let minValue2: number let minItem: Item for (const item of list) { if (fn(item) == false) continue let v1 = orderFn1(item) let v2 = orderFn2 != null ? orderFn2(item) : 0 if (minValue1 == null || v1 < minValue1 || (v1 == minValue1 && v2 < minValue2)) { minValue1 = v1 minValue2 = v2 minItem = item } } return minItem } /** 返回符合条件的最后一元素 */ static last(list: Item[], fn: (t: Item) => boolean, orderFn1: (item: Item) => number = null, orderFn2: (item: Item) => number = null): Item { if (list.length == 0) return null if (orderFn1 == null) { for (let i = list.length - 1; i >= 0; i--) { if (fn(list[i])) return list[i] } return null } // let maxValue1: number let maxValue2: number let maxItem: Item for (const item of list) { if (fn(item) == false) continue let v1 = orderFn1(item) let v2 = orderFn2 ? orderFn2(item) : 0 if (maxValue1 == null || v1 > maxValue1 || (v1 == maxValue1 && v2 > maxValue2)) { maxValue1 = v1 maxValue2 = v2 maxItem = item } } return maxItem } /** 取最大值 */ static max(list: T1[], fn: (item: T1) => T2, whereF: (item: T1) => boolean = null, defaultV: T2 = null): T2 { let maxV: T2 for (const i of list) { if (whereF && whereF(i) == false) continue let v = fn(i) if (maxV == undefined) { maxV = fn(i) } else { if (v > maxV) { maxV = v } } } if (maxV != undefined) return maxV return defaultV } /** 最小值 */ static min(list: Item[], fn: (item: Item) => T, whereF: (item: Item) => boolean = null, defaultV: T = null): T { let minV: T for (const i of list) { if (whereF && whereF(i) == false) continue let v = fn(i) if (minV == undefined) { minV = v } else { if (v < minV) { minV = v } } } if (minV != undefined) return minV return defaultV } /** 累加 */ static sum(list: Item[], fn: (item: Item) => number, wn?: (item: Item) => boolean): number { let v: number = 0 for (const t of list) { if (wn && wn(t) == false) continue v = v + fn(t) } return v } /** 平均值 */ static avg(list: Item[], fn: (item: Item) => number): number { if (this.length == 0) return 0 let sum = ArrayExt.sum(list, fn) return sum / this.length } /** 排序 */ static sortBy(list: Item[], fn: (item: Item) => number, fn2: (item: Item) => number = null) { if (fn2 == null) return list.sort((a: Item, b: Item): number => fn(a) - fn(b)) else return list.sort((a: Item, b: Item): number => fn(a) == fn(b) ? (fn2(a) - fn2(b)) : fn(a) - fn(b)) } /** 降序 排序 */ static sortByDescending(list: Item[], fn: (item: Item) => number) { list.sort((a: Item, b: Item): number => fn(b) - fn(a)) } /** 排序成新的数组 */ static orderBy(list: Item[], fn: (item: Item) => number, fn2: (item: Item) => number = null): Item[] { let newList = list.concat([]) if (fn2 == null) return newList.sort((a: Item, b: Item): number => fn(a) - fn(b)) else return newList.sort((a: Item, b: Item): number => fn(a) == fn(b) ? (fn2(a) - fn2(b)) : fn(a) - fn(b)) } /** 降序成新的数组 */ static orderByDescending(list: Item[], fn: (item: Item) => number, fn2: (item: Item) => number = null): Item[] { let newList = list.concat([]) if (fn2 == null) return list.sort((a: Item, b: Item): number => fn(b) - fn(a)) else return list.sort((a: Item, b: Item): number => fn(a) == fn(b) ? (fn2(b) - fn2(a)) : fn(b) - fn(a)) } /** 分组 */ static groupBy(list: Item[], fn: (item: Item) => gT): GroupItem[] { let groups = new Array>() for (const item of list) { let key = fn(item) let group = groups.find(t => t.key == key) if (group == null) { group = new GroupItem(key) groups.push(group) } group.push(item) } return groups } /** * 选择 * let newObjectList = ArrayExt.Select(list,t=>({pA:t.name, pB:t.age + "_"+ t.month}) ) ; */ static Select(list: Item[], fn: (item: Item) => rT): rT[] { let newList = new Array() for (const t of list) { newList.push(fn(t)) } return newList } /** 过来,并按顺序排序 */ static where(list: Item[], whereFn: (item: Item) => boolean, orderfn1: (item: Item) => number = null, orderfn2: (item: Item) => number = null): Item[] { let newList = list.filter(whereFn) if (orderfn1 == null && orderfn2 == null) return newList return ArrayExt.sortBy(newList, orderfn1, orderfn2) } } export class GroupItem { key: gT get count() { return this.list.length } list: Item[] constructor(k: gT) { this.key = k this.list = [] } push(d: Item) { this.list.push(d) } } /** * 对排序好的数组进行去重操作 * @param {(e1, e2) => boolean} [checkFuction] 校验对象相等函数 * @returns {Array} 返回自身 */ export function arrayRemoveDuplicateBySort(arr: Array, checkFuction: (e1: T, e2: T) => boolean = checkEqual): Array { if (arr.length < 2) return arr let j = 1 for (let i = 1, l = arr.length; i < l; i++) if (!checkFuction(arr[j - 1], arr[i])) arr[j++] = arr[i] arr.length = j return arr }