UNPKG

many-dimansional-sparse-array

Version:

多维稀疏数组,一维数组存储方案,可能有维度扩展缺陷,可能有单元素复用缺陷

108 lines (97 loc) 3.73 kB
/** * 多维稀疏数组 * 一维数组存储方案,可能有维度扩展缺陷,可能有单元素复用缺陷 * 维度从左向右上升,后面的高度全部为0可以做省略 * 每层维度的下标从0开始,到length-1结束 */ export default class ManyDimansionalSparseArray<T> { private lengthOfAxis: number[]; // 轴长 private body: any[]; // 一维稀疏数组存储体 private baseNumberOfEveryDimansional: number[] = new Array(); // 每个维度的基数 constructor(...args: number[]) { this.lengthOfAxis = args; // 初始化轴长 // 计算一维数组长度, 并且计算每个维度的基数 let lengthOfBody: number = this.lengthOfAxis.reduceRight((total, curr) => { this.baseNumberOfEveryDimansional.unshift(total * curr); return this.baseNumberOfEveryDimansional[0]; }, 1); // 完善基数数组 this.baseNumberOfEveryDimansional.shift(); this.baseNumberOfEveryDimansional.push(1); this.body = Array(lengthOfBody); // 初始化一维数组 } /** * 多维数组值取得 * @param args 多维数组的下标集合(可变参) * @returns 多维数组值 */ public get(...args: number[]): T { let indexOfBody: number = this.calculateindexOfBody(...args); return this.body[indexOfBody]; } /** * 多维数组值设定 * @param value 要设定的值 * @param args 多维数组的下标集合(可变参) */ public set(value: T, ...args: number[]): void { let indexOfBody: number = this.calculateindexOfBody(...args); this.body[indexOfBody] = value; } /** * 计算多维坐标在一维数组中的下标,与其他进制转10进制相似 * @param args 多维数组的下标集合(可变参) * @returns 一维稀疏数组存储体 */ public calculateindexOfBody(...args: number[]): number { return args.reduce((total, x, i) => total + x * this.baseNumberOfEveryDimansional[i], 0); } /** * 元素循环 * @param callback * @param isEachAll 是否循环全部,默认:false */ public forEach( callback: (value: T, ...args: number[]) => void, isEachAll: boolean = false ): void { if (isEachAll) { // 循环所有元素 this.forEachAll(callback); } else { // Array.forEach会跳过empty部分 this.body.forEach((value, i) => { callback(value, ...this.calculateIndexsOfManyDimansionalArray(i)); }); } } /** * 循环所有元素 * @param callback */ private forEachAll(callback: (value: T, ...args: number[]) => void): void { for (let i: number = 0; i < this.body.length; i++) { // 遍历所有元素 callback(this.body[i], ...this.calculateIndexsOfManyDimansionalArray(i)); // 执行回调 } } /** * 计算多维数组的下标集合 * 轴长:一维3,二维4,三维5 * 基数:一维20(一维最小下标),二维5(二维最小下标),三维1(三维最小下标) * 存储体一维数组最大小标:59 * 一维 坐标:2(59 / 20) 剩余:19(59 % 20) * 二维 坐标:3(19 / 5) 剩余:4(19 % 5) * 三维 坐标:4(4 / 1) 剩余:0(4 % 1) * @param indexOfBody 一维数组的下标 * @returns 多维数组的下标集合 */ public calculateIndexsOfManyDimansionalArray(indexOfBody: number): number[] { let ret: number[] = new Array(); this.baseNumberOfEveryDimansional.reduce((residue, baseNumber) => { ret.push(Math.floor(residue / baseNumber)); // 计算当前维度下标 return residue % baseNumber; // 计算剩余 }, indexOfBody); return ret; } }