Pregunta

Me gustaría escribir una función JavaScript que valida un código postal, comprobando si El código postal realmente existe. Aquí hay una lista de todos los códigos postales:

http://www.census.gov/tiger/tms/gazetteer /zips.txt (solo me importa la segunda columna)


Esto es realmente un problema de compresión. Me gustaría hacer esto por diversión. OK, ahora que está fuera del camino, aquí hay una lista de optimizaciones sobre una tabla hash en la que puedo pensar, siéntase libre de agregar cualquier cosa que no haya pensado:

  • Divida el código postal en 2 partes, los primeros 2 dígitos y los últimos 3 dígitos.
  • Haga una declaración gigante if-else, primero verifique los primeros 2 dígitos, luego verifique los rangos dentro de los últimos 3 dígitos.
  • O convierta las cremalleras en hexadecimal y vea si puedo hacer lo mismo con grupos más pequeños.
  • Averigüe si dentro del rango de todos los códigos postales válidos hay más códigos postales válidos versus códigos postales no válidos. Escriba el código anterior dirigido al grupo más pequeño.
  • Divida el hash en archivos separados y cárguelos a través de Ajax a medida que el usuario ingresa el código postal. Entonces, quizás divida en 2 partes, primero para los primeros 2 dígitos, segundo para los últimos 3.

Por último, planeo generar los archivos JavaScript usando otro programa, no a mano.

Editar: el rendimiento importa aquí. Quiero usar esto, si no apesta. Rendimiento de la ejecución del código JavaScript + tiempo de descarga.

Edición 2: soluciones solo de JavaScript, por favor. No tengo acceso al servidor de aplicaciones, además, eso lo convertiría en otro problema =)

¿Fue útil?

Solución

  

Me gustaría escribir una función de JavaScript que valide un código postal

Podría ser más esfuerzo del que vale la pena, manteniéndolo actualizado para que en ningún momento se rechace el código postal válido real de alguien. ¡También puede probar un servicio externo o hacer lo que todos los demás hacen y simplemente aceptar cualquier número de 5 dígitos!

  

Aquí hay una lista de optimizaciones sobre una tabla hash directa que puedo imaginar

Lamento estropear la diversión potencial, pero es probable que no vaya a administrar un rendimiento real mucho mejor que el que le brinda el Objeto de JavaScript cuando se utiliza como una tabla hash. El acceso de los miembros objeto es una de las operaciones más comunes en JS y estará super-optimizado; construir sus propias estructuras de datos es improbable que las supere, incluso si son estructuras potencialmente mejores desde el punto de vista de la informática. En particular, cualquier cosa que use & # 8216; Array & # 8217; no va a funcionar tan bien como cree porque Array se implementa como un objeto (tabla hash) en sí mismo.

Dicho esto, una posible herramienta de compresión de espacio si solo necesita saber 'válido o no' sería usar un campo de bits de 100000 bits, empaquetado en una cadena. Por ejemplo, para un espacio de solo 100 códigos postales, donde los códigos 032-043 son & # 8216; válidos & # 8217 ;:

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)) );
}

Ahora solo tenemos que encontrar la manera más eficiente de llevar el campo de bits al script. La versión anterior '\ x00' llena ingenua es bastante ineficiente. Los enfoques convencionales para reducir eso serían, por ejemplo, para codificarlo en base64:

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

Eso llevaría las 100000 banderas a 16.6kB. Desafortunadamente, atob es solo para Mozilla, por lo que se necesitaría un decodificador base64 adicional para otros navegadores. (No es demasiado difícil, pero es un poco más de tiempo de inicio para la descodificación). También puede ser posible utilizar una solicitud AJAX para transferir una cadena binaria directa (codificada en texto ISO-8859-1 a responseText). Eso lo bajaría a 12.5kB.

Pero en realidad, probablemente cualquier cosa, incluso la versión ingenua, funcionaría siempre y cuando sirviera el script con mod_deflate, lo que comprimiría gran parte de esa redundancia, y también la repetición de '\ x00' para todos los rangos largos de & # 8216; inválido & # 8217; códigos.

Otros consejos

Podría hacer lo impensable y tratar el código como un número (recuerde que en realidad no es un número). Convierta su lista en una serie de rangos, por ejemplo:

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

luego para probar:

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

esto solo está usando una búsqueda lineal muy ingenua (O (n)). Si mantuvo la lista ordenada y utilizó la búsqueda binaria, podría lograr O (log n).

Utilizo API de Google Maps para verificar si existe un código postal.

Es más preciso.

Suponiendo que tiene las cremalleras en una matriz ordenada (parece justo si está controlando la generación de la estructura de datos), vea si una búsqueda binaria simple es lo suficientemente rápida.

Entonces ... ¿Está haciendo la validación del lado del cliente y desea optimizar el tamaño del archivo? Probablemente no puedas superar la compresión general. Afortunadamente, la mayoría de los navegadores admiten gzip para ti, por lo que puedes usarlo de forma gratuita.

¿Qué tal un simple dictado o lista con código json con los códigos postales en orden ordenado y busca el dictado? se comprimirá bien, ya que es una secuencia predecible, se importará fácilmente ya que es json, utilizando el analizador incorporado en los navegadores, y la búsqueda probablemente también sea muy rápida, ya que es una primitiva de JavaScript.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top