Como criar uma matriz de objetos literais em um loop?

224

Eu preciso criar uma matriz de literais de objeto como este:

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

Em um loop como este:

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

O valor de keydeve estar results[i].labelem cada elemento da matriz.

codecowboy
fonte

Respostas:

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
fonte
18
você pode pular o var obj = {bit, basta pressionar o literal em si.
31511 Peter Bailey
3
cálculo comprimento apenas uma vez é provavelmente uma boa ideia, eu optar por adicionar um var objpara tornar o código mais claro, é claro que você pode ignorá-lo, você pode escrever o roteiro inteiro em uma linha se você deseja :)
RaYell
3
@ kangax, o comprimento não é "calculado", é uma operação O (1).
Triptych
8
@ Triptych - Sim, mas é uma pesquisa de propriedade que você executa a cada iteração, que não é gratuita e pode ser evitada. Micro-otimização? Possivelmente. Além disso, é um valor "ativo" - se você modificar a matriz no loop, o comprimento será alterado em iterações sucessivas que podem levar ao infinito. Dê este um relógio youtube.com/watch?v=mHtdZgou0qU
Peter Bailey
2
Sim, mas você não está modificando a matriz a cada iteração. Se você fosse, seria ridículo comparar com o comprimento de qualquer maneira na maioria dos casos.
Triptych
61

A resposta de RaYell é boa - responde à sua pergunta.

Parece-me, no entanto, que você realmente deveria criar um objeto codificado por rótulos com 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;

A abordagem acima deve ser muito mais rápida e idiomática do que pesquisar em toda a matriz de objetos uma chave para cada acesso.

Tríptico
fonte
+1 vez que a solução chave, faz mais sentido e me ajuda com as minhas necessidades :)
winner_joiner
parece que falta um ponto e vírgula depois de definir a chave var?
superUntitled
boa resposta, estive procurando como acessar as informações por um tempo, obrigado
thatOneGuy 17/07/2015
e se a chave precisar ser mais de uma vez! ['notas'] podem ocorrer mais de uma vez, o que podemos fazer?
Milson
1
Milson - nesse caso, não é realmente uma "chave"
Triptych
13

Você pode fazer algo assim no ES6.

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

É nisso que o Array # map é bom

var arr = oFullResponse.results.map(obj => ({
    key: obj.label,
    sortable: true,
    resizeable: true
}))
Sem fim
fonte
4

Isso 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
fonte
4

Na mesma idéia de Nick Riggs, mas eu crio um construtor e empurro um novo objeto na matriz usando-o. Evita a repetição das teclas da classe:

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
fonte
3

Eu criaria a matriz e acrescentaria os literais do objeto a ela.

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
fonte
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
fonte
7
É melhor iniciar uma matriz usando em []vez de new Array().
RaYell 17/08/09
Discussão interessante [] vs. new Array () stackoverflow.com/questions/7375120/…
Adrian P.
2

Se você quiser ir além do @tetra com o ES6, use a sintaxe de propagação do objeto e faça algo assim:

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

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