1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/**
* [start, end]
*/
export interface ICellRange {
/**
* zero based index
*/
start: number;
/**
* zero based index
*/
end: number;
}
export function isICellRange(candidate: any): candidate is ICellRange {
if (!candidate || typeof candidate !== 'object') {
return false;
}
return typeof (<ICellRange>candidate).start === 'number'
&& typeof (<ICellRange>candidate).end === 'number';
}
export function cellIndexesToRanges(indexes: number[]) {
indexes.sort((a, b) => a - b);
const first = indexes.shift();
if (first === undefined) {
return [];
}
return indexes.reduce(function (ranges, num) {
if (num <= ranges[0][1]) {
ranges[0][1] = num + 1;
} else {
ranges.unshift([num, num + 1]);
}
return ranges;
}, [[first, first + 1]]).reverse().map(val => ({ start: val[0], end: val[1] }));
}
export function cellRangesToIndexes(ranges: ICellRange[]) {
const indexes = ranges.reduce((a, b) => {
for (let i = b.start; i < b.end; i++) {
a.push(i);
}
return a;
}, [] as number[]);
return indexes;
}
export function reduceCellRanges(ranges: ICellRange[]): ICellRange[] {
const sorted = ranges.sort((a, b) => a.start - b.start);
const first = sorted[0];
if (!first) {
return [];
}
return sorted.reduce((prev: ICellRange[], curr) => {
const last = prev[prev.length - 1];
if (last.end >= curr.start) {
last.end = Math.max(last.end, curr.end);
} else {
prev.push(curr);
}
return prev;
}, [first] as ICellRange[]);
}
export function cellRangesEqual(a: ICellRange[], b: ICellRange[]) {
a = reduceCellRanges(a);
b = reduceCellRanges(b);
if (a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (a[i].start !== b[i].start || a[i].end !== b[i].end) {
return false;
}
}
return true;
}
/**
* todo@rebornix test and sort
* @param range
* @param other
* @returns
*/
export function cellRangeContains(range: ICellRange, other: ICellRange): boolean {
return other.start >= range.start && other.end <= range.end;
}
|