Home > other >  Is there a good way to infer ranges of numbers from postal codes?
Is there a good way to infer ranges of numbers from postal codes?

Time:09-25

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.

  • Related