¿Cómo crear una matriz de literales de objetos en un bucle?

224

Necesito crear una matriz de literales de objetos como este:

var myColumnDefs = [
    {key:"label", sortable:true, resizeable:true},
    {key:"notes", sortable:true,resizeable:true},......

En un bucle como este:

for (var i = 0; i < oFullResponse.results.length; i++) {
    console.log(oFullResponse.results[i].label);
}

El valor de keydebe estar results[i].labelen cada elemento de la matriz.

codecowboy
fuente

Respuestas:

395
var arr = [];
var len = oFullResponse.results.length;
for (var i = 0; i < len; i++) {
    arr.push({
        key: oFullResponse.results[i].label,
        sortable: true,
        resizeable: true
    });
}
RaYell
fuente
18
puede omitir el var obj = {bit, simplemente presione el literal en sí.
Peter Bailey
3
calcular la longitud de una sola vez es probablemente una buena idea, decido agregar una var objpara hacer el código más claro, por supuesto, puede saltar, puede escribir el guión entero en una sola línea si desea :)
RaYell
3
@kangax, la longitud no se "calcula", es una operación O (1).
Tríptico
8
@Triptych: sí, pero es una búsqueda de propiedades que ejecuta con cada iteración, que no es gratuita y se puede evitar. Micro-optimización? Posiblemente. Además, es un valor "en vivo": si modifica la matriz en el bucle, la longitud cambiará en iteraciones sucesivas que podrían conducir al infinito. Dale un vistazo a
Peter Bailey
2
Sí, pero no estás modificando la matriz en cada iteración. Si lo fuera, sería ridículo comparar con la longitud de todos modos en la mayoría de los casos.
Tríptico
61

La respuesta de RaYell es buena: responde a su pregunta.

Sin embargo, me parece que realmente debería crear un objeto con etiquetas con subobjetos como valores:

var columns = {};
for (var i = 0; i < oFullResponse.results.length; i++) {
    var key = oFullResponse.results[i].label;
    columns[key] = {
        sortable: true,
        resizeable: true
    };
}

// Now you can access column info like this. 
columns['notes'].resizeable;

El enfoque anterior debería ser mucho más rápido e idiomático que buscar una clave para cada acceso en toda la matriz de objetos.

Tríptico
fuente
+1 desde la solución clave, tiene más sentido y me ayuda con mis necesidades :)
winner_joiner
parece que le falta un punto y coma después de configurar la clave var?
SuperUntitled
buena respuesta,
he
¿Qué pasa si la clave necesita ser más de una vez? ['notas'] pueden aparecer más de una vez, ¿qué podemos hacer?
Milson
1
Milson - en ese caso, no es realmente una "clave"
Tríptico
13

Puedes hacer algo así en ES6.

new Array(10).fill().map((e,i) => {
   return {idx: i}
});
tetra master
fuente
12

Esto es en lo que Array # map es bueno

var arr = oFullResponse.results.map(obj => ({
    key: obj.label,
    sortable: true,
    resizeable: true
}))
Sin fin
fuente
4

Esto funcionará:

 var myColumnDefs = new Object();
 for (var i = 0; i < oFullResponse.results.length; i++) {
     myColumnDefs[i] = ({key:oFullResponse.results[i].label, sortable:true, resizeable:true});
  }
Manjunath Raddi
fuente
4

En la misma idea de Nick Riggs pero creo un constructor, y empujo un nuevo objeto en la matriz al usarlo. Evita la repetición de las claves de la clase:

var arr = [];
var columnDefs = function(key, sortable, resizeable){
    this.key = key; 
    this.sortable = sortable; 
    this.resizeable = resizeable;
    };

for (var i = 0; i < len; i++) {
    arr.push((new columnDefs(oFullResponse.results[i].label,true,true)));
}
JPIyo
fuente
3

Crearía la matriz y luego le agregaría los literales del objeto.

var myColumnDefs = [];

for ( var i=0 ; i < oFullResponse.results.length; i++) {

    console.log(oFullResponse.results[i].label);
    myColumnDefs[myColumnDefs.length] = {key:oFullResponse.results[i].label, sortable:true, resizeable:true};
}
BenM
fuente
3
var myColumnDefs = new Array();

for (var i = 0; i < oFullResponse.results.length; i++) {
    myColumnDefs.push({key:oFullResponse.results[i].label, sortable:true, resizeable:true});
}
Nick Riggs
fuente
77
Es mejor iniciar una matriz usando en []lugar de new Array().
RaYell
Interesante debate [] vs. New Array () stackoverflow.com/questions/7375120/…
Adrian P.
2

Si desea ir más allá de @tetra con ES6, puede usar la sintaxis de propagación de objetos y hacer algo como esto:

let john = {
    firstName: "John",
    lastName: "Doe",
};

let people = new Array(10).fill().map((e, i) => {(...john, id: i});
Pe Wu
fuente