JavaScript中实现类似于Java 的 数组操作
直接上代码(TypeScript写法)
/**
* ArrayAgg - 数据组合工具
* https://www.yangguangdream.com/?id=2269
*
*
* 用法:
* ArrayAgg.of(list).mapToInt(x => x.price * x.count).sum()
* ArrayAgg.of(list).sumBy(x => x.count)
* ArrayAgg.of(list).count(x => x.count > 0)
* ArrayAgg.of(list).anyMatch(x => x.count > 0)
* ArrayAgg.of(list).allMatch(x => x.count > 0)
* ArrayAgg.of(list).mapToInt(x => x.count).sum()
* ArrayAgg.of(list).mapToInt(x => x.count).count()
* ArrayAgg.of(list).mapToInt(x => x.count).avg()
* ArrayAgg.of(list).mapToInt(x => x.count).min()
* ArrayAgg.of(list).mapToInt(x => x.count).max()
*/
export class ArrayAgg<T> {
private readonly arr: readonly T[];
private constructor(arr: readonly T[]) {
this.arr = arr ?? [];
}
//实例化
static of<T>(arr: readonly T[] | null | undefined): ArrayAgg<T> {
return new ArrayAgg<T>(arr ?? []);
}
//就是类似Java里面的mapToInt,返回IntAgg对象(数字聚合器,用来进行计算)
mapToInt(selector: (item: T, index: number) => number): IntAgg {
const nums = this.arr.map((it, i) => selector(it, i));
return new IntAgg(nums);
}
//直接对对象数组按字段求和:sumBy(x => x.xxx)
sumBy(selector: (item: T, index: number) => number): number {
return this.mapToInt(selector).sum();
}
//直接计数(可选predicate过滤)
count(predicate?: (item: T, index: number) => boolean): number {
if (!predicate) return this.arr.length;
let c = 0;
for (let i = 0; i < this.arr.length; i++) if (predicate(this.arr[i], i)) c++;
return c;
}
//anyMatch:是否存在任意一个元素满足条件 ,类似于 Array.some()
anyMatch(predicate: (item: T, index: number) => boolean): boolean {
for (let i = 0; i < this.arr.length; i++) if (predicate(this.arr[i], i)) return true;
return false;
}
//allMatch:是否所有元素都满足条件,类似于 Array.every()
allMatch(predicate: (item: T, index: number) => boolean): boolean {
for (let i = 0; i < this.arr.length; i++) if (!predicate(this.arr[i], i)) return false;
return true;
}
}
//数字聚合器类:sum/avg/min/max
export class IntAgg {
private readonly nums: readonly number[];
constructor(nums: readonly number[]) {
this.nums = nums ?? [];
}
//mapToInt(xxx).sum() 求和
sum(): number {
let s = 0;
for (let i = 0; i < this.nums.length; i++) {
const n = this.nums[i];
// 忽略 NaN / Infinity(按你需要也可以改成 throw)
if (Number.isFinite(n)) s += n;
}
return s;
}
//mapToInt(xxx).count() 计数
count(): number {
return this.nums.length;
}
//mapToInt(xxx).avg() 平均值
avg(): number {
const c = this.count();
return c === 0 ? 0 : this.sum() / c;
}
//mapToInt(xxx).min() 最小值
min(): number | undefined {
let m: number | undefined = undefined;
for (const n of this.nums) {
if (!Number.isFinite(n)) continue;
if (m === undefined || n < m) m = n;
}
return m;
}
//mapToInt(xxx).max() 最大值
max(): number | undefined {
let m: number | undefined = undefined;
for (const n of this.nums) {
if (!Number.isFinite(n)) continue;
if (m === undefined || n > m) m = n;
}
return m;
}
}

微信扫码查看本文
发表评论