Convertir archivo CSV al diccionario JSON?

Necesito convertir un conjunto de datos CSV grande a JSON, sin embargo, la salida debería ser un diccionario JSON como este:

var products = { "crystal": { "description": "This is a crystal", "price": "2.95" }, "emerald": { "description": "This is a emerald", "price": "5.95" } }; 

Así es como se vería la tabla CSV: introduzca la descripción de la imagen aquí

Estoy usando un script al que se hace referencia aquí para generar el JSON:

 var csv = require('csv') var fs = require('fs') var f = fs.createReadStream('Fielding.csv') var w = fs.createWriteStream('out.txt') w.write('['); csv() .from.stream(f, {columns:true}) .transform(function(row, index) { return (index === 0 ? '' : ',\n') + JSON.stringify(row); }) .to.stream(w, {columns: true, end: false}) .on('end', function() { w.write(']'); w.end(); }); 

Sin embargo, la salida de ese script se crea en este formato:

 [ { "name": "crystal", "description": "This is a crystal", "price": "2.95" }, { "name": "emerald", "description": "This is a emerald", "price": "5.95" } ] 

¿Cómo modificaría el script para obtener el formato de “diccionario” deseado?

Todo lo que necesita hacer es recorrer la matriz y usar item.name como clave para su objeto de diccionario

 var products ={}; data.forEach(function(item){ products[item.name] = item; }); 

Esto dejará la propiedad de name en el elemento, pero eso no debería ser un problema

Creo que algo como esto funcionaría:

 var products_arr = [{"name":"crystal","description":"This is a crystal","price":"2.95"}, {"name":"emerald","description":"This is a emerald","price":"5.95"}] var products = {}; for (var i = 0, l = products_arr.length ; i < l ; ++i) { var x = products_arr[i]; var name = x.name delete x.name; // deletes name property from JSON object products[name] = x; } 

Esto dará como resultado:

 { "crystal": { "description": "This is a crystal", "price": "2.95" }, "emerald": { "description": "This is a emerald", "price": "5.95" } } 

Encontré la librería csv parser más útil:

 var csvText=`status,path,name,ext,checksum,size,document_service_id,document_service_path,message success,./15-02-2017_17-11/d77c7886-ffe9-40f2-b2fe-e68410d07891//expE1.txt,expE1.txt,txt,38441337865069eabae7754b29bb43e1,414984,8269f7e3-3221-49bb-bb5a-5796cf208fd1,/neuroinftest/20170215/expE1.txt, success,./15-02-2017_17-11/d77c7886-ffe9-40f2-b2fe-e68410d07891//expE10.txt,expE10.txt,txt,f27e46979035706eb0aaf58c26e09585,368573,2c94ed19-29c9-4660-83cf-c2148c3d6f61,/neuroinftest/20170215/expE10.txt, success,./15-02-2017_17-11/d77c7886-ffe9-40f2-b2fe-e68410d07891//expE2.txt,expE2.txt,txt,e1040d9546423c823944120de0e5c46c,333308,b3898f5d-1058-4cf3-acf9-76759117b810,/neuroinftest/20170215/expE2.txt, ` var csv = require('csv'); csv.parse(csvText, {columns: true}, function(err, data){ console.log(JSON.stringify(data, null, 2)); }); 

En la variable csvText tengo mi archivo separado por comas, con la primera línea como encabezado. Utilizo la función de parse y estoy pasando las {columns: true} para indicar que la primera línea tiene los encabezados. El segundo parámetro en la función de callback ( data ) tiene el objeto con claves que son los encabezados y los valores que son las celdas csv correspondientes. Utilizo JSON.stringify para imprimirlo bien y el objeto de resultado tiene este aspecto (lo coloca en una matriz):

 [ { "status": "success", "path": "./15-02-2017_17-11/d77c7886-ffe9-40f2-b2fe-e68410d07891//expE1.txt", "name": "expE1.txt", "ext": "txt", "checksum": "38441337865069eabae7754b29bb43e1", "size": "414984", "document_service_id": "8269f7e3-3221-49bb-bb5a-5796cf208fd1", "document_service_path": "/neuroinftest/20170215/expE1.txt", "message": "" }, { "status": "success", "path": "./15-02-2017_17-11/d77c7886-ffe9-40f2-b2fe-e68410d07891//expE10.txt", "name": "expE10.txt", "ext": "txt", "checksum": "f27e46979035706eb0aaf58c26e09585", "size": "368573", "document_service_id": "2c94ed19-29c9-4660-83cf-c2148c3d6f61", "document_service_path": "/neuroinftest/20170215/expE10.txt", "message": "" }, { "status": "success", "path": "./15-02-2017_17-11/d77c7886-ffe9-40f2-b2fe-e68410d07891//expE2.txt", "name": "expE2.txt", "ext": "txt", "checksum": "e1040d9546423c823944120de0e5c46c", "size": "333308", "document_service_id": "b3898f5d-1058-4cf3-acf9-76759117b810", "document_service_path": "/neuroinftest/20170215/expE2.txt", "message": "" } ] 

UPD : esta matriz se puede convertir fácilmente en el objeto que necesita con reduce :

 var res_obj = data.reduce(function(acc, cur, i) { acc[cur.name] = cur; return acc; }, {}); 

En mi caso utilizo la propiedad del nombre como clave. Asegúrate de que sea único.

Si desea modificar su código específico, puede cambiar la línea

  return (index === 0 ? '' : ',\n') + JSON.stringify(row); 

a

  var clonedRow = JSON.parse(JSON.stringify(row)); var key = clonedRow['name']; delete clonedRow['name']; var newRow = {}; newRow[key] = clonedRow; return (index === 0 ? '' : ',\n') + JSON.stringify(newRow); 

Esto crea un nuevo objeto para cada fila, modificando la estructura de acuerdo con su requerimiento.

Lo mejor que puedes hacer es utilizar PapaParse , un potente analizador / descargador csv. Admite secuencias, varias codificaciones de cadena, fila de encabezado y es rápido.