Написание функции проверки почтового индекса JavaScript - PullRequest
1 голос
/ 05 марта 2009

Я хотел бы написать JavaScript функцию, которая проверяет почтовый индекс, проверяя, существует ли фактически почтовый индекс. Вот список всех почтовых индексов:

http://www.census.gov/tiger/tms/gazetteer/zips.txt (я забочусь только о 2-й колонке)


Это действительно проблема сжатия. Я хотел бы сделать это для удовольствия. Хорошо, теперь это не так, вот список оптимизаций по прямой хеш-таблице, о которых я могу думать, не стесняйтесь добавлять все, о чем я не думал:

  • Разбить почтовый индекс на 2 части, первые 2 цифры и последние 3 цифры.
  • Сделайте гигантский оператор if-else, сначала проверяя первые 2 цифры, затем проверяя диапазоны в пределах последних 3 цифр.
  • Или конвертируйте молнии в гекс и посмотрите, смогу ли я сделать то же самое, используя меньшие группы.
  • Выясните, есть ли в диапазоне всех действительных почтовых индексов больше действительных почтовых индексов по сравнению с недействительными почтовыми кодами. Напишите приведенный выше код, ориентированный на меньшую группу.
  • Разбейте хеш на отдельные файлы и загрузите их через Ajax, когда пользователь вводит почтовый индекс. Так что, возможно, разбить на 2 части, сначала для первых 2 цифр, второй для последних 3.

Наконец, я планирую генерировать файлы JavaScript с помощью другой программы, а не вручную.

Редактировать: производительность имеет значение здесь. Я хочу использовать это, если это не отстой. Производительность выполнения кода JavaScript + время загрузки.

Редактировать 2: JavaScript только решения, пожалуйста. У меня нет доступа к серверу приложений, плюс, это превратило бы это в совершенно другую проблему =)

Ответы [ 6 ]

4 голосов
/ 05 марта 2009

Вы можете сделать немыслимое и трактовать код как число (помните, что на самом деле это не число). Преобразуйте ваш список в серию диапазонов, например:

zips = [10000, 10001, 10002, 10003, 23001, 23002, 23003, 36001]
// becomes
zips = [[10000,10003], [23001,23003], [36001,36001]]
// make sure to keep this sorted

затем для проверки:

myzip = 23002;
for (i = 0, l = zips.length; i < l; ++i) {
    if (myzip >= zips[i][0] && myzip <= zips[i][1]) {
        return true;
    }
}
return false;

это просто использование очень наивного линейного поиска (O (n)). Если вы сохраняете список отсортированным и используете бинарный поиск, вы можете достичь O (log n).

2 голосов
/ 05 марта 2009

Я хотел бы написать функцию JavaScript, которая проверяет почтовый индекс

Может потребоваться больше усилий, чем стоит, с обновлением, чтобы ни в коем случае не был отклонен чей-то действительный почтовый индекс. Вы также можете попробовать внешнюю услугу или сделать то, что делают все остальные, и просто принять любой 5-значный номер!

вот список оптимизаций для простой хеш-таблицы, которую я могу придумать

Извините, что испортил потенциальную забаву, но вы, вероятно, не сможете управлять гораздо большей фактической производительностью, чем дает объект JavaScript при использовании в качестве хеш-таблицы. Доступ к элементу объекта является одной из наиболее распространенных операций в JS и будет супероптимизирован; построение ваших собственных структур данных вряд ли превзойдет их, даже если они являются потенциально лучшими структурами с точки зрения информатики. В частности, все, что использует Array, не будет работать так же хорошо, как вы думаете, потому что Array фактически реализован как сам объект (hashtable).

Сказав это, возможный инструмент сжатия пространства, если вам нужно знать только «действительный или нет», будет использовать 100-битное битовое поле, упакованное в строку. Например, для пробела всего 100 почтовых индексов, где коды 032-043 являются «действительными»:

var zipfield= '\x00\x00\x00\x00\xFF\x0F\x00\x00\x00\x00\x00\x00\x00';
function isvalid(zip) {
    if (!zip.match('[0-9]{3}'))
        return false;
    var z= parseInt(zip, 10);
    return !!( zipfield.charCodeAt(Math.floor(z/8)) & (1<<(z%8)) );
}

Теперь нам нужно найти наиболее эффективный способ получить битовое поле в сценарии. Наивная '\ x00'-заполненная версия выше довольно неэффективна. Обычные подходы к сокращению этого были бы, например. закодировать в base64:

var zipfield= atob('AAAAAP8PAAAAAAAAAA==');

Это уменьшило бы 100000 флагов до 16,6 КБ. К сожалению, atob предназначен только для Mozilla, поэтому для других браузеров потребуется дополнительный декодер base64. (Это не слишком сложно, но для декодирования требуется немного больше времени.) Также возможно использовать запрос AJAX для передачи прямой двоичной строки (закодировано в тексте ISO-8859-1 в responseText). Это уменьшило бы его до 12,5 КБ.

Но на самом деле, вероятно, что-нибудь, даже наивная версия, будет делать, пока вы обслуживаете скрипт, используя mod_deflate, который сжимает большую часть этой избыточности, а также повторение \ x00 для всех длинных диапазонов «неверных» кодов.

1 голос
/ 05 марта 2009

Я использую API Карт Google , чтобы проверить, существует ли почтовый индекс.

Это точнее.

0 голосов
/ 05 марта 2009

Итак ... Вы проводите проверку на стороне клиента и хотите оптимизировать размер файла? Вы, вероятно, не можете победить общее сжатие. К счастью, большинство браузеров поддерживают gzip для вас, так что вы можете использовать это бесплатно.

Как насчет простого json-кодированного диктанта или списка с почтовыми индексами в отсортированном порядке, и посмотрите на dict. он будет хорошо сжиматься, поскольку является предсказуемой последовательностью, легко импортируется, поскольку это json, с использованием встроенного в браузер синтаксического анализатора, и поиск, вероятно, также будет очень быстрым, поскольку это примитив javascript.

0 голосов
/ 05 марта 2009
0 голосов
/ 05 марта 2009

Предполагая, что у вас есть почтовые индексы в отсортированном массиве (кажется справедливым, если вы управляете генерацией структуры данных), посмотрите, достаточно ли простой двоичный поиск.

...