Last active
January 21, 2020 06:21
-
-
Save shhider/eb5de4d581038c0bf8805cc0a83718ba to your computer and use it in GitHub Desktop.
[range intersection]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 传入两个范围字符串,返回交集;无交集或异常情况返回 null。 | |
* - 如果要考虑整行整列,通过解析为 Range 对象来处理会更清晰。 | |
*/ | |
function intersection(rangeA: string, rangeB: string): string | null { | |
const splitedA = splitRangeStr(rangeA) | |
const splitedB = splitRangeStr(rangeB) | |
if (!splitedA || !splitedB) { | |
return null | |
} | |
const [startColA, startRowA, endColA, endRowA] = splitedA | |
const [startColB, startRowB, endColB, endRowB] = splitedB | |
const notSec = endRowA < startRowB || startRowA > endRowB || endColA < startColB || startColA > endColB | |
if (notSec) { | |
return null | |
} | |
const startCol = startColA > startColB ? startColA : startColB | |
const startRow = startRowA > startRowB ? startRowA : startRowB | |
const endCol = endColA < endColB ? endColA : endColB | |
const endRow = endRowA < endRowB ? endRowA : endRowB | |
return `${startCol}${startRow}:${endCol}${endRow}` | |
} | |
/** | |
* 'A1:B2' => ['A', 1, 'B', 2] | |
*/ | |
function splitRangeStr(rangeStr: string): [string, number, string, number] | null { | |
if (!rangeStr || typeof rangeStr !== 'string') { | |
return null | |
} | |
const [startCellStr, endCellStr] = rangeStr.split(':') | |
const splitedStart = splitCellStr(startCellStr) | |
const splitedEnd = splitCellStr(endCellStr) | |
if (splitedStart && splitedEnd) { | |
const [startCol, startRow] = splitedStart | |
const [endCol, endRow] = splitedEnd | |
return [startCol, startRow, endCol, endRow] | |
} | |
return null | |
} | |
const regCell = /^([A-Za-z]*)([0-9]*)$/ | |
/** | |
* 'A1' => ['A', 1] | |
*/ | |
function splitCellStr(cellStr: string): [string, number] | null { | |
const matched = cellStr && regCell.exec(cellStr) | |
if (matched) { | |
return [matched[1], parseInt(matched[2])] | |
} | |
return null | |
} | |
///////// | |
test('intersection', () => { | |
expect(splitRangeStr('A1:B5')).toEqual(['A', 1, 'B', 5]) | |
expect(splitRangeStr('AA10:BB50')).toEqual(['AA', 10, 'BB', 50]) | |
expect(intersection('A1:C3', 'B2:D4')).toBe('B2:C3') | |
expect(intersection('C1:F4', 'A3:D6')).toBe('C3:D4') | |
expect(intersection('AA100:CC200', 'BB150:DD250')).toBe('BB150:CC200') | |
expect(intersection('A1:A2', 'A3:A4')).toBe(null) | |
expect(intersection('AA', 'B1:BB')).toBe(null) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment