Tengo un conjunto de datos como el siguiente,
// eg [{ id: 'M1', description: 'Lorem description', fields: [{ name: 'field_1', value: 'Lorem value 1' }] }]en la que necesito transformarme,
[ { id: 'M1', description: 'Lorem description', field_1: 'Lorem value 1' } ]Escribí el siguiente código para lograr esto. Y funciona bien, pero no creo que esta sea la mejor manera de hacerlo. ¿Cómo puedo hacer que mi solución funcione mejor? Porque esto es más lento cuando el conjunto de datos se hace más grande.
const _sampleData = [{ id: 'M1', description: 'Lorem description', fields: [{ name: 'field_1', value: 'Lorem value 1' }] }, { id: 'M2', description: 'Lorem description', fields: [{ name: 'field_1', value: 'Lorem value 1' }, { name: 'field_2', value: 'Lorem value 2' } ] } ]; function toObject(fields) { const out = {}; for (const field of fields) { out[field.name] = field.value; } return out; } function getFlatSampleData() { const data = []; for (const item of _sampleData) { let out = {}; for (const key in item) { if (Array.isArray(item[key])) { out = { ...out, ...toObject(item[key]) }; } else { out[key] = item[key]; } } data.push(out); } return data; } console.log(getFlatSampleData());La parte que parece ser la culpable es la siguiente:
out = { ...out, ...toObject(item[key]) };En cambio, dado que desea aplanar su objeto, podría hacer algo como esto:
let obj = [{ id: 'M1', description: 'Lorem description', fields: [{ name: 'field_1', value: 'Lorem value 1' }] }]; let output = {}; let itemQueue = [obj]; let limit = 0; while (limit < itemQueue.length) { for (let key in itemQueue[limit]) { if ((Array.isArray(itemQueue[limit][key])) || (typeof itemQueue[limit][key] === "object")) { if ((typeof itemQueue[limit][key].name !== "undefined") && (typeof itemQueue[limit][key].value !== "undefined")) { output[itemQueue[limit][key].name] = itemQueue[limit][key].value; } else { itemQueue.push(itemQueue[limit][key]) } } else { output[key] = itemQueue[limit][key]; } } limit++; } console.log(output);La idea es no generar nuevos objetos siempre, sino usar una combinación de una pila y un bucle.
Se espera que el tiempo de procesamiento requerido aumente a medida que los conjuntos de datos sean más grandes. El código solo accede una vez a cada elemento y la transformación no puede ocurrir en menos accesos. Entonces, desde una perspectiva computacional de alto nivel, su complejidad está bien. Además de las mejoras de código anteriores, podría proponer las siguientes dos cosas.
Preasignar la memoria necesaria para los objetos. En lugar de llamar empuja cada vez.
function getFlatSampleData() { const data = new Array(_sampleData.length); for (const item of _sampleData) { let out = {}; for (const key in item) { if (Array.isArray(item[key])) { out = { ...out, ...toObject(item[key]) }; } else { out[key] = item[key]; } } data.push(out); } return data; }
Use trabajadores o un marco JavaScript paralelo para paralelizar el proceso.