[Pregunta]: ¿Como puedo definir un arreglo de la siguiente manera con JS?

Iniciado por Leguim, 18 Agosto 2020, 01:17 AM

0 Miembros y 1 Visitante están viendo este tema.

Leguim

Quiero que se pueda..

Código (javascript) [Seleccionar]

console.log(arreglo['texto']); // que imprima el valor 7


traté de definir así..

Código (javascript) [Seleccionar]

var arreglo = ['texto' => 7];


pero no funciona, si me funciona si hago así..

Código (javascirpt) [Seleccionar]

var arreglo = [];
arreglo['texto'] = 7;


pero quiero hacerlo de una manera más ordenada como la que mencioné más arriba de todo aunque no se si es posible...

@XSStringManolo

Con arreglo["texto"] estás accediendo a la propiedad(variable) texto de un objeto arreglo. Es decir, cualquiera de las múltiples formas que te permitan definir o modificar las propuedades o el objeto te sirven.

Código (javascript) [Seleccionar]
var arreglo = {};
arreglo.texto = 7;


Código (javascript) [Seleccionar]
var arreglo = {};
arreglo["texto"] = 7;


Código (javascript) [Seleccionar]
var a = "texto";
var arreglo = {};
arreglo[a] = 7;


Código (javascript) [Seleccionar]
var arreglo = {
  texto: 7
};


Obviamente arreglo no es un arreglo como tal. javascript no tiene soporte nativo a arrays multidimensionales, pero si puedes crear arrays de arrays:

Código (javascript) [Seleccionar]
var arreglo = [
  ["texto", 7]
];


También tienes un montón de formas distintas de acceder a propiedades, valores, objetos, arrays... Varios for, .keys .entries... Etc.



#!drvy

Me imagino que tienes la confusión de los arrays en PHP.

En PHP un array puede tener keys de todo tipo, numéricos, string, null, etc.. En javascript los arrays solo pueden tener keys numéricos, si quieres usar string utilizas objetos tal y como te ha mostrado @XSStringManolo.


Saludos

Agente Naranja

Cita de: #!drvy en 19 Agosto 2020, 08:17 AM
Me imagino que tienes la confusión de los arrays en PHP.

En PHP un array puede tener keys de todo tipo, numéricos, string, null, etc.. En javascript los arrays solo pueden tener keys numéricos, si quieres usar string utilizas objetos tal y como te ha mostrado @XSStringManolo.


Saludos


Que yo sepa, en JS también puedes tener un array con índices no numericos:



Eso sí, en el fondo los Arrays en javascript son objetos. En el caso original creo que podría hacer

const arreglo = { texto: 7};
console.log(arreglo['texto'])

Y por favor, estamos en 2020. DEJA DE USAR VAR PARA DECLARAR VARIABLES. Lo de ahora es const o let. Usando Var puedes tener problema con los "scopes", porque declara variables con un alcance de función, mientras que let/var declaran un alcance de bloque. Algo así.

#!drvy

Cita de: Agente Naranja en 26 Agosto 2020, 08:31 AMQue yo sepa, en JS también puedes tener un array con índices no numericos:

Ahí lo que estas haciendo es acceder a las propiedades como objeto del array. Es como hacer trampa y los "indices" que seteas no funcionan como array.

https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Array

Arrays cannot use strings as element indexes (as in an associative array) but must use integers. Setting or accessing via non-integers using bracket notation (or dot notation) will not set or retrieve an element from the array list itself, but will set or access a variable associated with that array's object property collection. The array's object properties and list of array elements are separate, and the array's traversal and mutation operations cannot be applied to these named properties.


Una simple prueba:

Código (javascript) [Seleccionar]
let a = [];
a['indice'] = 'hola';
a['mundo'] = 'adios';

a.forEach(item => console.log(item)); //undefined

console.log(a.length); // 0

console.log(a.values()); // {}



Saludos

MinusFour

Lo más similar a un arreglo asociativo de php en JS es un mapa. Si quieres imitar el comportamiento de inicialización de PHP lo podrías hacer con una función.

Código (javascript) [Seleccionar]

let patm = arr => new Map(arr.map((el, i) => Array.isArray(el) ? el : [i, el]));


Código (javascript) [Seleccionar]

let m = patm([
   'lorem',
   'ipsum',
   ['text', 7]
]);


Para iterar:

Código (javascript) [Seleccionar]

m.forEach((el, k) => console.log(el, k));
// 0 'lorem', 1 'ipsum', 'text' 7


También conservas las propiedades que menciona #!drvy

Código (javascript) [Seleccionar]

console.log(m.size) //3
console.log([...m.values()]) // ['lorem', 'ipsum', 7]


Lo que no vas a poder hacer es acceder a las propiedades ni siquiera con notación de corchetes.

Código (javascript) [Seleccionar]

m[0] = 'test'; //escribe 'test' en la propiedad 0 del objeto del mapa, pero los elementos
              //del objeto no son parte del objeto del mapa.
m[1];          //La propiedad 1 del objeto del mapa no es el elemento del mapa al que corresponde la llave 1
m['text'];     //Lo mismo de arriba.


Si quieres cambiar esos elementos tienes que usar Map.prototype.get y Map.prototype.set:

Código (javascript) [Seleccionar]

m.set(0, 'nuevo valor');
console.log(m.get(0)); //'nuevo valor'


Podrías emular ese comportamiento con un Proxy, pero yo no lo haría. Perderías la posibilidad de tener llaves como forEach, size, values, entries, etc. Sin mencionar que los Proxies son mucho más lentos.

Por otro lado, puedes optar simplemente por un objeto normal:

Código (javascript) [Seleccionar]

let obj = {
   0 : 'lorem',
   1 : 'ipsum',
   'text' : 7
};


Y también puedes iterar esas propiedades con Object.values, Object.entries y Object.keys. Pero ojo, a diferencia de PHP y los mapas el orden no está exactamente "garantizado" y no es por orden de inserción. Hasta donde tengo entendido, la especificación no había aclarado un orden al cual todas las implementaciones pudieran llegar de una manera determinista hasta hace poco. Generalmente, las implementaciones se comportan de manera muy similar (al menos en sus últimas versiones).

También puede ser un arreglo:

Código (javascript) [Seleccionar]

let a = ['lorem', 'ipsum'];
a['text'] = 7;

console.log(Object.values(a));


Pero ya esto a mi me sabe muy mal.

En mi opinión me quedaba con los mapas de javascript.

@XSStringManolo

Cita de: Agente Naranja en 26 Agosto 2020, 08:31 AMY por favor, estamos en 2020. DEJA DE USAR VAR PARA DECLARAR VARIABLES. Lo de ahora es const o let. Usando Var puedes tener problema con los "scopes", porque declara variables con un alcance de función, mientras que let/var declaran un alcance de bloque. Algo así.
Puedes tener problemas si no tienes ni idea de que haces. El alcance de var depende del contexto de ejecución. Si está dentro de una función, tiene alcance local en esa función. Con bucles for pasa lo mismo. En el resto de casos el alcance es global y por tanto se define una propiedad en el objeto global/window.

Teniendo esto en cuenta, usar var en una IIFE o en un módulo es seguro porque no contaminas el objeto global. La única propiedad definida es el identificador de la propia IIFE si no es anónima o el identificador del objeto/módulo.

MinusFour

Cita de: @XSStringManolo en 27 Agosto 2020, 03:18 AMEl alcance de var depende del contexto de ejecución. Si está dentro de una función, tiene alcance local en esa función. Con bucles for pasa lo mismo.

Si por lo mismo te refieres a que el alcance sigue siendo local a la función y no al bucle entonces eso es correcto. Las variables definidas con var no tienen ningún alcance localizado a ninguna estructura de control.

Cita de: @XSStringManolo en 27 Agosto 2020, 03:18 AMTeniendo esto en cuenta, usar var en una IIFE o en un módulo es seguro porque no contaminas el objeto global. La única propiedad definida es el identificador de la propia IIFE si no es anónima o el identificador del objeto/módulo.

let y const sirven para mucho más... No tiene sentido declarar variables dentro de una estructura de control con var, las podrías poner todas al tope de tu función y no habría ninguna diferencia. Técnicamente, una IIFE con nombre es realmente una IINFE (Immediately Invoked Named Function Expression) y el nombre es local a la función y no es visible desde el contexto en el la expresión fue creada.

Código (javascript) [Seleccionar]

(function named() {
   console.log(named); //la funcion
})();

console.log(window.named == undefined) //true
console.log(named); //ReferenceError