2012-02-13 13 views
16

Tengo dos matrices:La combinación de dos matrices para formar un objeto Javascript

var columns = ["Date", "Number", "Size", "Location", "Age"]; 

var rows = [["2001", "5", "Big", "Sydney", "25"],["2005", "2", "Med", "Melbourne", "50"],["2012", "20", "Huge", "Brisbane", "80"]]; 

Estoy tratando de combinarlos en un objeto de javascript para cada elemento de la matriz filas. Después de eso, quiero insertar cada objeto en una nueva matriz.

igual:

var newarray = []; 

//'thing' should be the same structure for each row item 
var thing = { 
    "Date" : "2001", 
    "Number" : "5", 
    "Size":"Big", 
    "Location":"Sydney", 
    "Age":"25" 
} 

newarray.push(thing); 

puedo hacer esto cuando sé los nombres de las columnas, pero tengo que ser capaz de almacenar los datos de esta manera, cuando el nombre de la columna es desconocido - es decir, en base a la índices de la matriz de columnas.

lo intenté como esto antes:

 for(var y = 0; y < rows.length; y++){ 

      for(var i = 0; i < columns.length; i++){ 
       thing[columns[i]] = rows[i][i]; 
      } 
       newarray.push(thing) 
     } 

El código anterior sólo se almacena el primer punto una y otra vez (según rows.length).

No entiendo cómo combinar los nombres de columna con las filas para crear una matriz de objetos. El hecho de que 'filas' contenga matrices es especialmente confuso.

Respuesta

9

Crear un nuevo objeto thing al comienzo de cada iteración del bucle exterior. Si no lo hace, cada vez que diga thing[columns[i]] sobrescribirá las propiedades del mismo objeto, y cuando lo inserta en newarray, obtendrá una matriz llena de referencias al el mismo objeto. Además, en el interior del bucle de asegurarse de que recibe los índices derecha (que tienes actualmente [i][i] en lugar de [y][i]):

var newarray = [], 
    thing; 

for(var y = 0; y < rows.length; y++){ 
    thing = {}; 
    for(var i = 0; i < columns.length; i++){ 
     thing[columns[i]] = rows[y][i]; 
    } 
    newarray.push(thing) 
} 

"El hecho de que 'filas' contiene matrices es especialmente confuso .."

Para sus datos de ejemplo rows.length será de 3, y rows[0] es la matriz:

["2001", "5", "Big", "Sydney", "25"] 

rows[0][3] es "Sydney".

Utilizando eso como ejemplo, debería poder ver lo que rows[y][i] le dará para cada valor de y y i ...

1

Debe especificar la fila correcta. Estás usando la columna. Reemplace rows[i][i] con rows[y][i]. Además, parece que estás reutilizando el mismo objeto thing una y otra vez. En su lugar, debe definirlo nuevamente cada iteración a través de la matriz (var thing = {};).

var newarray = []; 
    for (var y = 0; y < rows.length; y++) { 
     var thing = {}; 
     for (var i = 0; i < columns.length; i++) { 
      thing[columns[i]] = rows[y][i]; 
     } 
     newarray.push(thing); 
    } 
+0

Gracias, lo intentó de esa manera, y estoy teniendo el mismo problema. Ver: [JSFiddle] (http://jsfiddle.net/tamarasaurus/V42Hx/). ¿Me estoy perdiendo de algo? – tamarasaurus

+0

@tamarasaurus, ¿viste mi última actualización? Agregué una parte especificando que necesitas establecer 'var thing = []' cada iteración del ciclo. Su JSFiddle no muestra eso. –

+0

Ver http://jsfiddle.net/V42Hx/2/ con el cambio agregado. Parece funcionar. –

0

sólo tiene que restablecer thing

for(var y = 0; y < rows.length; y++){ 
    for(var i = 0; i < columns.length; i++){ 
     thing[columns[i]] = rows[y][i]; 
    } 

    newarray.push(thing); 
    thing = {};  
} 

ver Boletín: fiddle

19

Se podría así hacer esto de una manera más centrada en los datos:

var columns = ["Date", "Number", "Size", "Location", "Age"]; 

var rows = [ 
    ["2001", "5", "Big", "Sydney", "25"], 
    ["2005", "2", "Med", "Melbourne", "50"], 
    ["2012", "20", "Huge", "Brisbane", "80"] 
]; 

var result = rows.map(function(row) { 
    return row.reduce(function(result, field, index) { 
    result[columns[index]] = field; 
    return result; 
    }, {}); 
}); 

De esta manera no tendría que hacer frente a las matrices temporales.

En caso de que su código debe trabajar en antiguos navegadores, así, me gustaría recomendar a echar un vistazo a underscore.js para el uso de map + reduce.

4

En caso de que utilice Underscore.js hay _.object(list, [values])

Y aquí es cómo se implementa:

_.object = function(list, values) { 
    if (list == null) return {}; 
    var result = {}; 
    for (var i = 0, length = list.length; i < length; i++) { 
    if (values) { 
     result[list[i]] = values[i]; 
    } else { 
     result[list[i][0]] = list[i][1]; 
    } 
    } 
    return result; 
}; 
+0

+1. Es bueno saber cómo hacer esto con javascript puro, pero ¿por qué reinventar la rueda? Esta es la mejor solución en mi humilde opinión. Es importante saber/usar subrayado o lodash. – Jess

3

Usando funcional sería como nnnnnn dijo, pero con una pequeña corrección

var columns = ["Date", "Number", "Size", "Location", "Age"]; 

var rows = [ 
    ["2001", "5", "Big", "Sydney", "25"], 
    ["2005", "2", "Med", "Melbourne", "50"], 
    ["2012", "20", "Huge", "Brisbane", "80"] 
]; 

var result = rows.map(function(row) { 
    return row.reduce(function(result, field, index) { 
    result[columns[index]] = field; 
    return result 
    }, {}); 
}); 
0

En lugar de recorrer toda la tabla, también puede usar la matriz de columnas para generar una clase de fila (usando defineProperty) y luego usar esa matriz clase de fila para envolver las matrices de fila en su matriz de filas. La matriz resultante de objetos Row se vincula a la matriz de filas original, de modo que los cambios en uno se reflejen en la otra. Dependiendo de su caso de uso, esto podría ser útil o un problema. Un ejemplo de trabajo se da en el siguiente fragmento.

var columns = ["Date", "Number", "Size", "Location", "Age"]; 
 

 
var rows = [ 
 
    ["2001", "5", "Big", "Sydney", "25"], 
 
    ["2005", "2", "Med", "Melbourne", "50"], 
 
    ["2012", "20", "Huge", "Brisbane", "80"] 
 
]; 
 

 
var table = create_table(columns, rows); 
 

 
// 
 
for (var i = 0; i<table.length; i++) { 
 
    document.writeln("The thing in " + table[i].Location + " is " + table[i].Size + "<br/>"); 
 
} 
 

 
// The rows in table are still tied to those in the rows variable 
 
table[0].Size = "Small"; 
 
document.writeln(JSON.stringify(rows[0])); 
 

 
function create_table(columns, rows) { 
 
    // Create a Row class with the given columns 
 
    for (var i=0; i<columns.length; i++) { 
 
    var c = columns[i]; 
 
    Object.defineProperty(Row.prototype, c, { 
 
     enumerable: true, 
 
     get: getter(i), 
 
     set: setter(i), 
 
    }); 
 
    } 
 
    // Wrap the rows in row objects and return the resulting array 
 
    var r = new Array(rows.length); 
 
    for (var i=0; i<rows.length; i++) { 
 
    r[i] = new Row(rows[i]); 
 
    } 
 
    return r; 
 

 
    function Row(row) { this._ = row; } 
 

 
    // Generators for the getter and setter functions, with variable i stored in a closure. 
 
    function getter(i) { 
 
    return function(){ 
 
     return this._[i]; 
 
    }; 
 
    } 
 
    function setter(i) { 
 
    return function(val){ 
 
     return this._[i] = val; 
 
    }; 
 
    } 
 
}

0

Creo que mi solución es resolver su problema

código:

var keys = columns, 
     values = rows, 
     finalarray = []; 

     values.forEach((data,index) =>{ 
      var objJSON = new Object(); 
      for (i = 0; i < keys.length; i++) { 
       objJSON[keys[i]] = data[i]; 
       } 
      finalarray.push(objJSON); 
     }); 

respuesta:

console.log(finalarray) 

[{ 
    "Date" : "2001", 
    "Number" : "5", 
    "Size":"Big", 
    "Location":"Sydney", 
    "Age":"25" 
}, 
... 
}] 
0

Se puede utilizar esta función siguiente código ES6:

const assemblyData = (columns, rows) => { 
    return rows.map((row) => { 
     return row.reduce((res, field, index) => { 
     res[columns[index]] = field; 
     return res 
     }, {}); 
    }); 
} 
Cuestiones relacionadas