|
14 | 14 | * limitations under the License. |
15 | 15 | */ |
16 | 16 |
|
| 17 | +import type { IRange } from '../sheets/typedef'; |
| 18 | +import type { Nullable } from './types'; |
17 | 19 | import { Range } from '../sheets/range'; |
18 | 20 | import { ObjectMatrix } from './object-matrix'; |
19 | 21 | import { Rectangle } from './rectangle'; |
20 | | -import type { IRange } from '../sheets/typedef'; |
21 | | -import type { Nullable } from './types'; |
22 | 22 |
|
23 | 23 | function maximalRectangle<T>(matrix: T[][], match: (val: T) => boolean) { |
24 | 24 | if (matrix.length === 0 || matrix[0].length === 0) return null; |
@@ -90,14 +90,34 @@ function resetMatrix<T>(matrix: Nullable<T>[][], range: IRange) { |
90 | 90 | */ |
91 | 91 | export function queryObjectMatrix<T>(matrix: ObjectMatrix<T>, match: (value: T) => boolean) { |
92 | 92 | const arrayMatrix = matrix.toFullArray(); |
| 93 | + const rows = arrayMatrix.length; |
| 94 | + const cols = rows > 0 ? arrayMatrix[0].length : 0; |
93 | 95 | const results: IRange[] = []; |
94 | | - while (true) { |
| 96 | + |
| 97 | + // Limit iterations to prevent excessive computation. Each iteration extracts at least |
| 98 | + // one maximal rectangle, so 1000 is a generous upper bound for practical use cases. |
| 99 | + const MAX_ITERATIONS = 1000; |
| 100 | + let iterations = 0; |
| 101 | + |
| 102 | + while (iterations < MAX_ITERATIONS) { |
| 103 | + iterations++; |
95 | 104 | const rectangle = maximalRectangle(arrayMatrix, match); |
96 | 105 | if (!rectangle) { |
97 | 106 | break; |
98 | 107 | } |
99 | 108 |
|
100 | 109 | results.push(rectangle); |
| 110 | + |
| 111 | + // If the rectangle covers the entire matrix, no need to continue. |
| 112 | + if ( |
| 113 | + rectangle.startRow === 0 && |
| 114 | + rectangle.startColumn === 0 && |
| 115 | + rectangle.endRow === rows - 1 && |
| 116 | + rectangle.endColumn === cols - 1 |
| 117 | + ) { |
| 118 | + break; |
| 119 | + } |
| 120 | + |
101 | 121 | resetMatrix(arrayMatrix, rectangle); |
102 | 122 | } |
103 | 123 |
|
|
0 commit comments