Convert JavaScript Object Array

2

You would need to convert an object returned from an AJAX call to another object with different properties.

The object in question has a structure similar to this:

[
    {
        campo1: "algun valor",
        campo2: { Id: 12345567, Nombre: "Algun otro dato" },
        campo3: { Id: 12345567, Nombre: "Algun otro dato" },
        campo4: { Nombre: "Algun otro dato", Valor: 23456678 },
        campo5: { Id: 12345567, Nombre: "Algun otro dato" },
        campo6: false
    },
    {
        campo1: "algun valor x",
        campo2: { Id: 12345567, Nombre: "Algun otro dato" },
        campo3: { Id: 12345567, Nombre: "Algun otro dato" },
        campo4: { Nombre: "Algun otro dato 2", Valor: 234566789 },
        campo5: { Id: 1234557, Nombre: "Algun otro datx" },
        campo6: true
    }, 
]

And I need something like this:

{
    campo2: [
        { Id: 12345567, Nombre: "Algun otro dato" }
    ],
    campo3: [
        { Id: 12345567, Nombre: "Algun otro dato" }
    ],
    campo4: [
        { Nombre: "Algun otro dato", Valor: 23456678 },
        { Nombre: "Algun otro dato 2", Valor: 234566789 }
    campo5: [
        { Id: 12345567, Nombre: "Algun otro dato" },
        { Id: 1234557, Nombre: "Algun otro datx" }
    ]
}

I have tried to use some of the functions of a higher order but it shows that I lack knowledge, because I can not hit the spot. In short, I try to create the set of a dropdown so that it is:

<select id="campo2">
    <option value="12345567">Algun otro dato</option>
</select>
<select id="campo3">
    <option value="12345567">Algun otro dato</option>
</select>
<select id="campo4">
    <option value="23456678">Algun otro dato</option>
    <option value="234566789">Algun otro dato 2</option>
</select>
<select id="campo5">
    <option value="12345567">Algun otro dato</option>
    <option value="1234557">Algun otro datx</option>
</select>
  

Note : It should be noted that I do not have the information that comes from the AJAX call, so I do not know the values that it has, nor how many fields, nor what fields. Basically they are fields generated dynamically from the database.

     

Note 2 : If fixed, the fields brought in the second object are filtered:

     
  • There are no values that are not objects.
  •   
  • Objects are not repeated.
  •   
  • No two (or more) parent objects.
  •   

Edition 1: In response to @ a-cedano , the second JSON is generated according to the previous conversions, given the following considerations:

     
  • Names must be grouped into a single object.
  •   
  • Only properties whose values are of object type are preserved.
  •   
  • The values must be grouped in the same name, leaving only the unique values.
  •   

What would be the best (or some) way to face this? I suppose using those higher order functions (good).

I had tried something like the following (on a trial basis), but it still did not work for me:

    let data = [
    {
        campo1: "algun valor",
        campo2: { Id: 12345567, Nombre: "Algun otro dato" },
        campo3: { Id: 12345567, Nombre: "Algun otro dato" },
        campo4: { Nombre: "Algun otro dato", Valor: 23456678 },
        campo5: { Id: 12345567, Nombre: "Algun otro dato" },
        campo6: false
    },
    {
        campo1: "algun valor x",
        campo2: { Id: 12345567, Nombre: "Algun otro dato" },
        campo3: { Id: 12345567, Nombre: "Algun otro dato" },
        campo4: { Nombre: "Algun otro dato 2", Valor: 234566789 },
        campo5: { Id: 1234557, Nombre: "Algun otro datx" },
        campo6: true
    }, 
];

 const datos = [];
 data.forEach(d => {
   for(var prop in d) {
    if(typeof d[prop] === 'object') {
      let match = datos.find(x => Object.keys(x).indexOf('prop'));
        if(datos.length < 1 || match < 0)
        datos.push({ [prop]: d[prop] });
      else {
       if(datos[prop])
         datos[prop].push(d[prop]);
     }
    }
   }
 });

I appreciate any constructive comments.

    
asked by Maramal 08.08.2018 в 22:59
source

1 answer

0

Well, I hope someone posts something similar but better done, because although it fulfills the need, this code seems the opposite of "good practices" in JS:

	let data = 	[
			{
				campo1: "algun valor",
				campo2: { Id: 12345567, Nombre: "Algun otro dato" },
				campo3: { Id: 12345567, Nombre: "Algun otro dato" },
				campo4: { Nombre: "Algun otro dato", Valor: 23456678 },
				campo5: { Id: 12345567, Nombre: "Algun otro dato" },
				campo6: false
			},
			{
				campo1: "algun valor x",
				campo2: { Id: 12345567, Nombre: "Algun otro dato" },
				campo3: { Id: 12345567, Nombre: "Algun otro dato" },
				campo4: { Nombre: "Algun otro dato 2", Valor: 234566789 },
				campo5: { Id: 1234557, Nombre: "Algun otro datx" },
				campo6: true
			}, 
		];
	// Definimos nuevo objeto vacío
	const datos = {};
	// Iteramos el array de objetos existente
	 data.forEach(dato => {
	  // Iteramos las propiedades de cada objeto
		Object.keys(dato).forEach(prop =>  {
		// Si el valor de la propiedad iterada es de tipo objeto
		if(typeof dato[prop] === 'object') {
			// Si existe la propiedad en el objeto nuevo
			if(datos[prop]) {
			  // Si la propiedad del objeto nuevo es un array
				if(Array.isArray(datos[prop])) {
				// Buscamos si existe un objeto con el ID del dato iterado en el array del nuevo objeto
				let match = datos[prop].find(datoProp => {
					if(datoProp.Id)
						return datoProp.Id === dato[prop].Id;
				  else if(datoProp.Valor)
					return datoProp.Valor === dato[prop].Valor;
				});
				// Si no existe el objeto iterado en el nuevo objeto, lo añadimos al array del nuevo objeto
				if(!match)
					datos[prop].push(dato[prop]);
			  }
			} else {
				// Añadimos la propiedad y su valor iterada al nuevo objeto
			  let arr = []
			  arr.push(dato[prop]);
				datos[prop] = arr;
			}
		  }
		});
	  });
    console.info(datos);
    
answered by 09.08.2018 в 15:12