2010-11-22 21 views
168

Cómo se puede crear el equivalente JavaScript/jQuery de este código Java:Cómo crear un mapa sencillo usando JavaScript/jQuery

Map map = new HashMap(); //Doesn't not have to be a hash map, any key/value map is fine 
map.put(myKey1, myObj1); 
map.put(myKey2, myObj2); //Repeat n times 

function Object get(k) { 
    return map.get(k); 
} 

Respuesta

263

Editar: Fuera de respuesta fecha, ECMAScript 2015 (ES6) javascript estándar tiene una mapa aplicación, lea aquí para obtener más información: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

var map = new Object(); // or var map = {}; 
map[myKey1] = myObj1; 
map[myKey2] = myObj2; 

function get(k) { 
    return map[k]; 
} 

//map[myKey1] == get(myKey1); 
+10

Actualicé mi respuesta para usar un 'nuevo Object()' en lugar de 'new Array()'. Ver [este artículo] (http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/) –

+0

¿Cómo podemos proporcionar un nodo raíz aquí? – Krishnan

+0

¿Cómo podemos eliminar un pagador de valores clave del mapa? –

60

sólo tiene que utilizar los objetos lisos:

var map = { key1: "value1", key2: "value2" } 
function get(k){ 
    return map[k]; 
} 
+0

Las claves no se debe especificar como cadenas, es decir, sin comillas – lilalinux

13
var map = {'myKey1':myObj1, 'mykey2':myObj2}; 
// You don't need any get function, just use 
map['mykey1'] 
6

Si no está limitado a JQuery, puede usar el marco prototype.js. Tiene una clase llamada Hash: incluso puede usar JQuery & prototype.js juntos. Simplemente escriba jQuery.noConflict();

var h = new Hash(); 
h.set("key", "value"); 
h.get("key"); 
h.keys(); // returns an array of keys 
h.values(); // returns an array of values 
23
function Map() { 
    this.keys = new Array(); 
    this.data = new Object(); 

    this.put = function (key, value) { 
     if (this.data[key] == null) { 
      this.keys.push(key); 
     } 
     this.data[key] = value; 
    }; 

    this.get = function (key) { 
     return this.data[key]; 
    }; 

    this.remove = function (key) { 
     this.keys.remove(key); 
     this.data[key] = null; 
    }; 

    this.each = function (fn) { 
     if (typeof fn != 'function') { 
      return; 
     } 
     var len = this.keys.length; 
     for (var i = 0; i < len; i++) { 
      var k = this.keys[i]; 
      fn(k, this.data[k], i); 
     } 
    }; 

    this.entrys = function() { 
     var len = this.keys.length; 
     var entrys = new Array(len); 
     for (var i = 0; i < len; i++) { 
      entrys[i] = { 
       key: this.keys[i], 
       value: this.data[i] 
      }; 
     } 
     return entrys; 
    }; 

    this.isEmpty = function() { 
     return this.keys.length == 0; 
    }; 

    this.size = function() { 
     return this.keys.length; 
    }; 
} 
+4

Al menos, ponga todos esos métodos en el prototipo. – Bergi

+0

@Bergi porque ...? – rgtk

+3

@Adshi: [¿Uso de 'prototipo' frente a 'esto' en Javascript?] (Https://stackoverflow.com/questions/310870/use-of-prototype-vs-this-in-javascript) – Bergi

18

Se trata de una cuestión de edad, sino porque las respuestas existentes podrían ser muy peligroso, quería dejar esta respuesta para aquellas personas futuras que podrían tropezar aquí ...

El las respuestas basadas en el uso de un Objeto como HashMap están rotas y pueden causar consecuencias extremadamente desagradables si usa cualquier otra cosa que no sea una Cadena como clave. El problema es que las propiedades del objeto se fuerzan a cadenas usando el método .toString. Esto puede conducir a la siguiente maldad:

function MyObject(name) { 
    this.name = name; 
}; 
var key1 = new MyObject("one"); 
var key2 = new MyObject("two"); 

var map = {}; 
map[key1] = 1; 
map[key2] = 2; 

Si estabas esperando que el objeto se comportarían de la misma manera que un mapa de Java aquí, sería bastante molesto para descubrir que el mapa sólo contiene uno entrada con el cadena de clave [object Object]:

> JSON.stringify(map); 
{"[object Object]": 2} 

Esto es claramente no un reemplazo para HashMap de Java. Curiosamente, dada su edad, Javascript actualmente no tiene un objeto de mapa de propósito general. Sin embargo, hay esperanza en el horizonte: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map aunque un vistazo a la tabla de compatibilidad del navegador mostrará que esto aún no está listo para usarse en aplicaciones web de propósito general.

Mientras tanto, lo mejor que puede hacer es:

  • utilizan deliberadamente cadenas como claves. Es decir. utilice cadenas explícitas como claves en lugar de confiar en el .toString -ing implícito de las claves que usa.
  • Asegúrese de que los objetos que está utilizando como claves tengan un método .toString() bien definido que se ajuste a su comprensión de la singularidad de estos objetos.
  • Si no puede/no desea cambiar .toString de los objetos clave, al almacenar y recuperar las entradas, convierta los objetos en una cadena que represente su comprensión de la singularidad. P.ej. map[toUniqueString(key1)] = 1

A veces, sin embargo, eso no es posible. Si desea asignar datos en función de, por ejemplo, objetos de archivo, no existe una manera confiable de hacerlo porque los atributos que expone el objeto Archivo no son suficientes para garantizar su exclusividad. (Puede tener dos objetos File que representen archivos diferentes en el disco, pero no hay forma de distinguirlos en JS en el navegador).En estos casos, desafortunadamente, todo lo que puede hacer es refactorizar su código para eliminar la necesidad de almacenarlos en un futuro; quizás, usando una matriz en su lugar y haciendo referencia a ellos exclusivamente por índice.

Cuestiones relacionadas