diff options
-rwxr-xr-x | bin/reduceOverlap.js | 1 | ||||
-rw-r--r-- | lib/unitsToRanges.js | 23 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | test/unitsToRanges.js | 43 |
4 files changed, 68 insertions, 1 deletions
diff --git a/bin/reduceOverlap.js b/bin/reduceOverlap.js index d302cbb..ab4f6e7 100755 --- a/bin/reduceOverlap.js +++ b/bin/reduceOverlap.js @@ -4,6 +4,7 @@ const fs = require('fs') const { Readable, Transform, pipeline } = require('stream') const ndjson = require('ndjson') const cloneDeep = require('clone-deep') +const unitsToRanges = require('../lib/unitsToRanges.js') const argv = require('yargs/yargs')(process.argv.slice(2)) .option('debug', { diff --git a/lib/unitsToRanges.js b/lib/unitsToRanges.js new file mode 100644 index 0000000..8ffd7b0 --- /dev/null +++ b/lib/unitsToRanges.js @@ -0,0 +1,23 @@ +/** + * Convert a list of unit numbers into an addr:flats list. eg. converts 1,2,3,5 into 1-3;5 + * + * @param {Array} units + * + * @returns {string} addr:flats list + */ +module.exports = (units) => { + // adapted from https://stackoverflow.com/a/54973116/6702659 + const unitRanges = units + .slice() + .sort((a, b) => a - b) + .reduce((acc, cur, idx, src) => { + if ((idx > 0) && ((cur - src[idx - 1]) === 1)) { + acc[acc.length - 1][1] = cur + } else { + acc.push([cur]) + } + return acc + }, []) + .map(range => range.join('-')) + return unitRanges.length ? unitRanges.join(';') : null +} diff --git a/package.json b/package.json index 13dc6ab..a3a45f0 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "author": "Andrew Harvey <andrew@alantgeo.com.au>", "license": "MIT", "scripts": { - "test": "./node_modules/.bin/tape test/toOSM.js test/cluster.js" + "test": "./node_modules/.bin/tape test/toOSM.js test/cluster.js test/unitsToRanges.js" }, "dependencies": { "capital-case": "^1.0.4", diff --git a/test/unitsToRanges.js b/test/unitsToRanges.js new file mode 100644 index 0000000..53d08aa --- /dev/null +++ b/test/unitsToRanges.js @@ -0,0 +1,43 @@ +const test = require('tape') + +const unitsToRanges = require('../lib/unitsToRanges.js') + +test('units list to addr:flats', t => { + t.same( + unitsToRanges([]), + null, + 'empty input returns empty output' + ) + + t.same( + unitsToRanges(['1'], 100), + '1', + 'single unit' + ) + + t.same( + unitsToRanges(['1', '3']), + '1;3', + 'two units without a range' + ) + + t.same( + unitsToRanges(['1', '2']), + '1-2', + 'two consecutive units form a range' + ) + + t.same( + unitsToRanges(['1', '2', '3']), + '1-3', + 'three consecutive units form a range' + ) + + t.same( + unitsToRanges(['1', '2', '4']), + '1-2;4', + 'range and singular' + ) + + t.end() +}) |