Kenny Cruz
Kenny Cruz

Reputation: 55

Error when creating array of objects in a javascript loop

I have a problem creating an array of objects. the problem is that you should only create 2 objects but you end up creating 8 objects, because each value of a property is inserted into a new object. I have an array of objects called columns, which is dynamic since the values and properties are changing

enter image description here
what I need is to create objects depending on the value of the row property, for example an object that only contains the same value of the row.

 example: [   
    { string1: 'CONTRAPARTIDA',string2: 'NOMBRE',string3: null, number1: 'Orden', number2: 'VALOR ENV.' number3: null},      object with row value = 1   
    { string1: 'CONTRAPARTIDA',string2: 'NOMBRE',string3: null, number1: 'Orden', number2: 'VALOR ENV.' number3: null},      //object with row value = 2    

With this code I try to create my 2 objects, but unfortunately more objects are created than desired.

 for(let a in columnas){
 //I can't do this validation because as the column array is dynamic I don't know how many rows come in //the array.
     //if(columnas[a].fila ==1)  
    
         arrayFinal.push({
      
    // validations to match the campoDb with the new array property and insert the value
                         string1: (columnas[a].campoDb==='STRING1' ? columnas[a].nombre : null),
                         string2:(columnas[a].campoDb==='STRING2' ? columnas[a].nombre : null),
                         string3: null,
                         number1: (columnas[a].campoDb==='NUMBER1' ? columnas[a].nombre : null),
                         number2:(columnas[a].campoDb==='NUMBER2' ? columnas[a].nombre : null),
                         number3: null,
                         });

enter image description here
but as an attachment in the image 8 objects are created and only one property is filled and the correct thing would be this only 2 objects with these values.

 Example: [   
{ string1: 'CONTRAPARTIDA',string2: 'NOMBRE',string3: null, number1: 'Orden', number2: 'VALOR ENV.' number3: null},   
{ string1: 'CONTRAPARTIDA',string2: 'NOMBRE',string3: null, number1: 'Orden', number2: 'VALOR ENV.' number3: null},

const columnas = [
  { nombre: 'ORDEN', fila: 1, campoDb: 'NUMBER1' },
  { nombre: 'CONTRAPARTIDA', fila: 1, campoDb: 'STRING1' },
  { nombre: 'NOMBRE', fila: 1, campoDb: 'STRING2' },
  { nombre: 'VALOR ENV.', fila: 1, campoDb: 'NUMBER2' },
  { nombre: 'ORDEN', fila: 2, campoDb: 'NUMBER1' },
  { nombre: 'CONTRAPARTIDA', fila: 2, campoDb: 'STRING1' },
  { nombre: 'NOMBRE', fila: 2, campoDb: 'STRING2' },
  { nombre: 'VALOR ENV.', fila: 2, campoDb: 'NUMBER2' },
];  

let arrayFinal = [];
 for(let a in columnas){
  if(columnas[a].fila ==1) //no puedo hacer esta validacion xq como el arreglo columna es dinamico no se cuantas filas vengan en el areglo
    arrayFinal.push({
     string1: (columnas[a].campoDb==='STRING1' ? columnas[a].nombre : null),
     string2:(columnas[a].campoDb==='STRING2' ? columnas[a].nombre : null),
     string3: null,
     number1: (columnas[a].campoDb==='NUMBER1' ? columnas[a].nombre : null),
     number2:(columnas[a].campoDb==='NUMBER2' ? columnas[a].nombre : null),
     number3: null,
     });arrayFinal


 }
   console.log(arrayFinal);

I need some solution or recommendation on what I can do or what I can change from my code to make what I'm trying to do easier.

Upvotes: 1

Views: 161

Answers (2)

Amauri
Amauri

Reputation: 550

const columnas = [
  { nombre: 'ORDEN', fila: 1, campoDb: 'NUMBER1' },
  { nombre: 'CONTRAPARTIDA', fila: 1, campoDb: 'STRING1' },
  { nombre: 'NOMBRE', fila: 1, campoDb: 'STRING2' },
  { nombre: 'VALOR ENV.', fila: 1, campoDb: 'NUMBER2' },
  { nombre: 'ORDEN', fila: 2, campoDb: 'NUMBER1' },
  { nombre: 'CONTRAPARTIDA', fila: 2, campoDb: 'STRING1' },
  { nombre: 'NOMBRE', fila: 2, campoDb: 'STRING2' },
  { nombre: 'VALOR ENV.', fila: 2, campoDb: 'NUMBER2' },
];  

// 1. split the columns into two groups based on 'fila'
const rows = [1, 2].map((n) => columnas.filter(row => row.fila === n) )

// 2. iterate through each group
const results = rows.map(row => {
  // these are the values of 'campoDb' we are looking for
  return [ "STRING1", "STRING2", "STRING3", "NUMBER1", "NUMBER2", "NUMBER3" ]
      .reduce((acc, campoDb) => {
      // 2a. try to find an object that contains "campoDb"
      const item = row.find(_ => _.campoDb === campoDb)

      // 2.b if found, use that object's 'nombre', else use null
      acc[campoDb.toLowerCase()] = item ?  item.nombre : null

      return acc
  }, {})
})

console.log(results)

Upvotes: 1

Mike Ezzati
Mike Ezzati

Reputation: 3166

You have to filter columns based on criteria and reduce the result into an object.

const columnas = [
  { nombre: 'ORDEN', fila: 1, campoDb: 'NUMBER1' },
  { nombre: 'CONTRAPARTIDA', fila: 1, campoDb: 'STRING1' },
  { nombre: 'NOMBRE', fila: 1, campoDb: 'STRING2' },
  { nombre: 'VALOR ENV.', fila: 1, campoDb: 'NUMBER2' },
  { nombre: 'ORDEN', fila: 2, campoDb: 'NUMBER1' },
  { nombre: 'CONTRAPARTIDA', fila: 2, campoDb: 'STRING1' },
  { nombre: 'NOMBRE', fila: 2, campoDb: 'STRING2' },
  { nombre: 'VALOR ENV.', fila: 2, campoDb: 'NUMBER2' },
]; 

var result = [1, 2].map(i => columnas.filter(c => c.fila === i).reduce((acc, cur) => { acc[cur.campoDb] = cur.nombre; return acc }, {}));

console.log(result)

Upvotes: 1

Related Questions