¿puede una matriz en JS ser asociativa Y indexada? Me gustaría poder buscar un elemento en la matriz por su posición o por un valor de clave ... posible?javascript array Y asociativo indexado?
Respuesta
El orden en que aparecen los objetos en una matriz javascript asociativa no está definido, y será diferente en las diferentes implementaciones. Por esa razón, no se puede contar realmente con una clave asociativa dada para estar siempre en el mismo índice.
EDIT:
como señala Perspx, no son realmente verdaderas matrices asociativas en JavaScript. La declaración foo["bar"]
es sólo azúcar sintáctica para foo.bar
Si confía en el navegador para mantener el orden de los elementos en un objeto, se podría escribir una función
function valueForIndex(obj, index) {
var i = 0;
for (var key in obj) {
if (i++ == index)
return obj[key];
}
}
Aunque se trata de una verdadera, en la práctica, todos los principales navegadores recorren las propiedades de un objeto en el orden en que se definieron. Esto no está en la especificación, por supuesto, pero vale la pena mencionarlo. –
+1 ¡Su sugerencia es el método más rápido! – mate64
No hay cosas tales como matrices asociativas en Javascript . Puede usar literales de objeto, que parecen como matrices asociativas, pero tienen propiedades desordenadas. Los conjuntos de JavaScript normales se basan en índices enteros y no pueden ser asociativos.
Por ejemplo, con este objeto:
var params = {
foo: 1,
bar: 0,
other: 2
};
Puede acceder a las propiedades del objeto, por ejemplo:
params["foo"];
Y también se puede iterar sobre el objeto con la declaración for...in
:
for(var v in params) {
//v is equal to the currently iterated property
}
Sin embargo, no hay una regla estricta sobre el orden de la propiedad iteración: dos iteraciones de su objeto literal podrían devolver las propiedades en diferentes órdenes.
En realidad, las matrices de JavaScript también pueden tener índices no enteros. Simplemente no tiene mucho en el camino de los métodos para tratar con ellos. – Nosredna
¿Te refieres a una cadena? en ese caso, no es una matriz, solo un objeto con propiedades. – roryf
Nosredna: las matrices JS no tienen índices clave, esos objetos JS se consideran literales de objeto. so: foo ["bar"] = 1; foo.bar === foo ["barra"]; // true foo ["bar"] === foo [0]; // falso Esta es una de las muchas peculiaridades sutiles de JS que desanima a la gente fácilmente. – linusthe3rd
Después de leer el Wikipedia definition of associative array, voy a romper con el conocimiento tradicional de JavaScript y decir "sí, JavaScript tiene matrices asociativas". Con las matrices de JavaScript, puede agregar, reasignar, eliminar y buscar valores por sus claves (y las claves pueden ser cadenas entrecomilladas), que es lo que Wikipedia dice que las matrices asociativas deberían ser capaces de hacer.
Sin embargo, parece que se está preguntando algo diferente: si puede buscar el mismo valor por índice o clave. Eso no es un requisito de matrices asociativas (vea el artículo de Wikipedia). Las matrices asociativas no tienen que darle la capacidad de obtener un valor por índice.
JavaScript arrays are very closely akin to JavaScript objects.
arr=[];
arr[0]="zero";
arr[1]="one";
arr[2]="two";
arr["fancy"]="what?";
Sí, eso es una matriz, y sí, puede salirse con índices no numéricos. (Si tiene curiosidad, después de todo esto, arr.length es 3.)
En la mayoría de los casos, creo que debe mantener los índices numéricos cuando utiliza matrices. Eso es lo que la mayoría de los programadores esperan, creo.
El enlace es a la publicación de mi blog sobre el tema.
Tenías razón cuando dijiste "Y puedes tener una matriz con índices no numéricos". Se me pasó por la cabeza de alguna manera, pero sé este hecho. –
Para ser pedante, "fantasía" no es un índice en la matriz, sino un atributo del objeto instancia de la matriz. – BaroqueBobcat
Sí, buen punto. Es por eso que digo que las matrices están estrechamente relacionadas con objetos en JavaScript. – Nosredna
Los objetos nativos JS solo aceptan cadenas como nombres de propiedad, lo cual es verdadero even for numeric array indices; las matrices difieren de los objetos normales solo en que la mayoría de las implementaciones JS almacenan las propiedades indexadas numéricamente de manera diferente (es decir, en una matriz real siempre que sean densas) y su configuración desencadenará operaciones adicionales (por ejemplo, ajuste de la propiedad length
).
Si está buscando un mapa que acepte claves arbitrarias, tendrá que usar un non-native implementation. La secuencia de comandos está pensada para una iteración rápida y no de acceso aleatorio por índices numéricos, por lo que podría no ser lo que estás buscando.
Una aplicación de barebones de un mapa que haría lo que estás pidiendo podría tener este aspecto:
function Map() {
this.length = 0;
this.store = {};
}
Map.prototype.get = function(key) {
return this.store.hasOwnProperty(key) ?
this.store[key] : undefined;
};
Map.prototype.put = function(key, value, index) {
if(arguments.length < 3) {
if(this.store.hasOwnProperty(key)) {
this.store[key].value = value;
return this;
}
index = this.length;
}
else if(index >>> 0 !== index || index >= 0xffffffff)
throw new Error('illegal index argument');
if(index >= this.length)
this.length = index + 1;
this[index] = this.store[key] =
{ index : index, key : key, value : value };
return this;
};
El argumento de index
put()
es opcional.
Se puede acceder a los valores en un mapa map
ya sea por el índice o clave a través de
map.get('key').value
map[2].value
var stuff = [];
stuff[0] = "foo";
stuff.bar = stuff[0]; // stuff.bar can be stuff["bar"] if you prefer
var key = "bar";
alert(stuff[0] + ", " + stuff[key]); // shows "foo, foo"
pero entonces, stuff.length ya no sería 1 porque has agregado .bar ¿verdad? por lo tanto, pasar por el índice realmente no funcionaría más. – puffpio
No: agregar una propiedad con nombre no aumenta la longitud; solo agregar un elemento por índice numérico aumenta la duración. Agregar "cosas [1000] = 'blah'" hará que la duración aumente a 1001, aunque solo se hayan agregado dos elementos indexados numéricamente y una propiedad con nombre. Diversión no lo es ;-) – NickFitz
Sí.
test = new Array();
test[0] = 'yellow';
test['banana'] = 0;
alert(test[test['banana']]);
Aunque estoy de acuerdo con las respuestas dadas, en realidad puedes lograr lo que dices con getters y setters. Por ejemplo:
var a = [1];
//This makes a["blah"] refer to a[0]
a.__defineGetter__("blah", function(){return this[0]});
//This makes a["blah"] = 5 actually store 5 into a[0]
a.__defineSetter__("blah", function(val){ this[0] = val});
alert(a["blah"]); // emits 1
a["blah"] = 5;
alert(a[0]); // emits 5
¿Es esto lo que estás buscando? Creo que hay una manera más moderna y diferente de hacer getters y setters pero no puedo recordar.
Ah, y si vas a hacer esto en un bucle, es probable que necesites cierres por cierto ... solo digo. – Ryan
var myArray = Array();
myArray["first"] = "Object1";
myArray["second"] = "Object2";
myArray["third"] = "Object3";
Object.keys(myArray); // returns ["first", "second", "third"]
Object.keys(myArray).length; // returns 3
si desea que el primer elemento a continuación, se puede usar como tal:
myArray[Object.keys(myArray)[0]]; // returns "Object1"
Vine aquí para querer saber si esto es una mala práctica o no, y en su lugar encontró una gran cantidad de personas apareciendo para no entender la pregunta.
Quería tener una estructura de datos que se ordenó pero podría indexarse por clave, por lo que no requeriría iteración para cada búsqueda.
Los tiempos prácticos esto es bastante simple, pero todavía no he leído nada sobre si es una práctica terrible o no.
var roygbiv = [];
var colour = { key : "red", hex : "#FF0000" };
roygbiv.push(colour);
roygbiv[colour.key] = colour;
...
console.log("Hex colours of the rainbow in order:");
for (var i = 0; i < roygbiv.length; i++) {
console.log(roygbiv[i].key + " is " + roygbiv[i].hex);
}
// input = "red";
console.log("Hex code of input colour:");
console.log(roygbiv[input].hex);
Lo importante es no cambiar nunca el valor de array [index] o array [clave] directamente una vez que el objeto está configurado o los valores ya no partido. Si la matriz contiene objetos, puede cambiar las propiedades de esos objetos y podrá acceder a las propiedades modificadas por cualquiera de los métodos.
La marea ha cambiado en este caso. Ahora puedes hacer eso ... ¡y MÁS! Usando Harmony Proxies definitivamente podrías resolver este problema de muchas maneras.
Deberá verificar que sus entornos de destino lo admitan con quizás un poco de ayuda del harmony-reflect cuña.
Hay un ejemplo muy bueno en Mozilla Developer Network sobre el uso de un Proxy en find an array item object by it's property, que prácticamente lo resume todo.
aquí está mi versión:
var players = new Proxy(
[{
name: 'monkey',
score: 50
}, {
name: 'giraffe',
score: 100
}, {
name: 'pelican',
score: 150
}], {
get: function(obj, prop) {
if (prop in obj) {
// default behavior
return obj[prop];
}
if (typeof prop == 'string') {
if (prop == 'rank') {
return obj.sort(function(a, b) {
return a.score > b.score ? -1 : 1;
});
}
if (prop == 'revrank') {
return obj.sort(function(a, b) {
return a.score < b.score ? -1 : 1;
});
}
var winner;
var score = 0;
for (var i = 0; i < obj.length; i++) {
var player = obj[i];
if (player.name == prop) {
return player;
} else if (player.score > score) {
score = player.score;
winner = player;
}
}
if (prop == 'winner') {
return winner;
}
return;
}
}
});
console.log(players[0]); // { name: 'monkey', score: 50 }
console.log(players['monkey']); // { name: 'monkey', score: 50 }
console.log(players['zebra']); // undefined
console.log(players.rank); // [ { name: 'pelican', score: 150 },{ name: 'giraffe', score: 100 }, { name: 'monkey', score: 50 } ]
console.log(players.revrank); // [ { name: 'monkey', score: 50 },{ name: 'giraffe', score: 100 },{ name: 'pelican', score: 150 } ]
console.log(players.winner); // { name: 'pelican', score: 150 }
- 1. Javascript: Agregar a un array asociativo
- 2. Ordenar un array asociativo en AWK
- 3. Comparar dos matrices Javascript - Asociativo
- 4. str_replace() con arreglo asociativo
- 5. JavaScript Array
- 6. inicializar un array asociativo de los valores y de cadena struct teclas
- 7. Javascript nuevo método Array y join()
- 8. javascript sorprendente array comparison
- 9. JavaScript Array/Struct
- 10. PHP read Javascript array
- 11. JSON to javaScript array
- 12. JavaScript Array Sintaxis
- 13. Array Javascript Problema
- 14. Array de Javascript Reverso
- 15. 2D array de Javascript
- 16. Javascript selecbox.options para array?
- 17. cómo insertar un elemento asociativo en una matriz en javascript?
- 18. PHP: arreglo asociativo de orden re
- 19. JavaScript Object Literals & Array Literals
- 20. objeto Array-como en javascript
- 21. Getter/setter en javascript array?
- 22. Reemplazar cadena en javascript array
- 23. Fundamentos del índice Javascript Array
- 24. Javascript: presione array en array con for loop
- 25. matriz de Ruby a un hash indexado?
- 26. ¿Cuál es la diferencia entre Array (1) y el nuevo Array (1) en JavaScript?
- 27. Diferencia entre int [] array y int array []
- 28. Diferencia entre array [n] y array []?
- 29. ¿Es asociativo de suma y multiplicación de coma flotante?
- 30. CoffeeScript “Array()” vs “new Array()”
esto es bastante viejo, pero se puede utilizar Object.keys (matriz) para obtener las claves con el fin –
usted es un programador PHP :) – nawfal