Tengo un archivo CSV a continuación y quiero crear un objeto javascript a partir de él.
Estoy tratando de extraer los elementos de la columna "categoría" y crear un objeto de jerarquía y luego colocar información debajo de la columna "color" en el nivel más bajo del objeto.
Meta:
A continuación se muestra lo que he intentado hasta ahora para extraer la información del CSV y qué seguro cómo proceder desde aquí. ¿Cuál es el mejor y más eficiente?
let csv = `id, category, year, color, price \n 01, SUV > AWD > Sport > Benz, 2017, blue, $20 \n 02, SUV > FWD > Family > Benz, 2018, black, $20 \n 03, Sedan > AWD > BNW, 2017, white, $30 \n 04, SUV > AWD > Sport > BNW, 2012, red, $30 \n 05, Seden > RWD > Toyota, 2019, white, $30` function extractCSV(csv){ let object = {} let data = csv.split('\n') for(let i = 1; i < data.length; i++){ let subData = data[i].split(',') for(let j = 1; j < subData.length; j++){ let header = subData[j].split(">") if(header.length > 1){ for(let k = 0; k < header.length; k++){ } } } } return object }Gracias por adelantado
Primero, la "mejor" de las dos respuestas.
Verá que sigue principalmente el mismo flujo con el que comenzó, sin embargo, elegí poner todo el análisis por adelantado, en algunos objetos intermedios. Esto permite que el último código se centre solo en construir nuestro árbol.
let csv = `id, category, year, color, price \n 01, SUV > AWD > Sport > Benz, 2017, blue, $20 \n 02, SUV > FWD > Family > Benz, 2018, black, $20 \n 03, Sedan > AWD > BNW, 2017, white, $30 \n 04, SUV > AWD > Sport > BNW, 2012, red, $30 \n 05, Sedan > RWD > Toyota, 2019, white, $30`; function parseCsv(csv) { let object = {}; // Parse/Sanitize all the data up front const rows = csv .split("\n") .filter((row, index) => index && row) .map((row) => { const columns = row.split(","); return { headers: columns[1].split(">").map((p) => p.trim()), color: columns[3].trim() }; }); // Then spin through the rows for (const row of rows) { let currentObj = object; // Then spin through the headers for (let hi = 0; hi < row.headers.length; ++hi) { const header = row.headers[hi]; // If it is the last header, assign the color to it if (hi === row.headers.length - 1) { currentObj[header] = row.color; break; } // Else we need to get or set another object level currentObj = currentObj[header] = currentObj[header] ?? {}; } } return object; } console.log(parseCsv(csv));En segundo lugar, tomé otro enfoque aquí. Encuentro algo de elegancia en una solución recursiva. Aunque probablemente sea más difícil de leer, lo más probable es que utilice más memoria y sea más lento, especialmente si la profundidad del documento/encabezado crece. ¡Pero lo incluí por diversión!
let csv = `id, category, year, color, price \n 01, SUV > AWD > Sport > Benz, 2017, blue, $20 \n 02, SUV > FWD > Family > Benz, 2018, black, $20 \n 03, Sedan > AWD > BNW, 2017, white, $30 \n 04, SUV > AWD > Sport > BNW, 2012, red, $30 \n 05, Sedan > RWD > Toyota, 2019, white, $30`; const parseCsv = (csv) => { const result = {}; // Parse/Sanitize all the data up front const rows = csv .split("\n") .filter((row, index) => index && row) .map((row) => { const columns = row.split(","); return { headers: columns[1].split('>').map(p => p.trim()), color: columns[3].trim() }; }); // The recursive function, takes in // {target} the current object in the tree we're at // {headers} the remaining headers to step through // {color} the color to assign to the last header const handleRow = (target, headers, color) => { // Last header, so just assign the color to it if (headers.length === 1) { target[headers[0]] = color; return; } // Else we need to get or set another object level const newTarget = (target[headers[0]] = target[headers[0]] ?? {}); // And call into the next level with it and the remaining headers handleRow(newTarget, headers.slice(1), color); }; for (const row of rows) { handleRow(result, row.headers, row.color); } return result; }; console.log(parseCsv(csv));