I have an array of zipcodes (Of various countries) of this format:
["100-1001","102-1000","102-1001","102-1002","100-1002","111","112","102-1003","113"]
I'll need to infer ranges from these numbers in the output format of:
[[upper1,lower1],[upper2,lower2]]
For the above example this would be:
[["100-1001","100-1002"]["102-1000","102-1003"]["111","113"]]
Is there a better way than to convert everything as flat numbers, removing the delimiters ,inferring their ranges and then re-adding delimiters?
Currently I have this logic for non-hyphenated postal codes -
getRanges(zipCodes) {
zipCodes.sort();
let length = 1;
let ranges = [];
for (let i = 1; i <= zipCodes.length; i ) {
if (i == zipCodes.length || zipCodes[i] - zipCodes[i - 1] != 1) {
if (length == 1) {
let upper = lower = zipCodes[i - length];
ranges.push({lower, upper});
}
else {
let lower = zipCodes[i - length];
let upper = zipCodes[i - 1];
ranges.push({lower, upper});
}
length = 1;
}
else {
length ;
}
}
return ranges;
}
But I feel the extra overhead of removing and re-adding delimiters could be avoided if there's a better way of parsing the ranges. thanks in advance
CodePudding user response:
A simple solution would be convert the input to a list of number,string
pairs, sort/classify based on the numbers and finally extract the strings from the result:
function getRanges(arr) {
let pairs = arr.map(s => [
Number(s.replace(/\D /g, '')),
s
])
pairs.sort((a, b) => a[0] - b[0])
let ranges = [], last = null
for (let p of pairs) {
if (last && last[1][0] === p[0] - 1)
last[1] = p
else
ranges.push(last = [p, p])
}
return ranges.map(r => [r[0][1], r[1][1]])
}
const zipCodes = [
"100-1000",
"100-1001",
"100-1002",
"100-1003",
"100-1005",
"200-1000",
"200-1001",
"200-1002",
"200-1006",
"111",
"112",
"114",
"115",
"116",
]
console.log(getRanges(zipCodes))
CodePudding user response:
The sort function can work with strings too. So without removing the -
this will order the array of zip-codes and group them by pairs:
Update: This code doesn't solve the OP requirements, but several people upvoted it, since it sorts & groups the zip-codes. (I think several people, including me, misunderstood how the grouping was supposed to take place).
The correct way is georg's answer and the only improvement I would think of, is sorting before doing the actual map
so it returns the same order as the original request. Otherwise I can't think of a better implementation, so I'll leave my original code that got upvoted if anyone finds it useful.