如何在从csv文件读取数据时将多个对象“合并”为一个json对象

时间:2017-12-12 22:13:34

标签: json node.js csv

我想将一些csv文件转换为nodejs中的json文件。

然而,json中的一些属性将是数组。现在我可以逐行读取csv文件:

{"price":1,"bedrooms":"Bedrooms (All Levels): 4"},
{"price":null,"bedrooms":"Bedrooms (Above Grade): 4"},
{"price":null,"bedrooms":"Master Bedroom: 21x15"},
{"price":null,"bedrooms":"Master Bedroom Bath: Full"},
{"price":null,"bedrooms":"2nd Bedroom: 14x13"},
{"price":null,"bedrooms":"3rd Bedroom: 15x14"},
{"price":null,"bedrooms":"4th Bedroom: 15x12"}

但我想得到这样的东西:

`{"price":1,"bedrooms":["Bedrooms (All Levels): 4","Bedrooms (Above 
Grade): 4","Master Bedroom: 21x15","Master Bedroom Bath: Full","2nd 
Bedroom: 14x13","3rd Bedroom: 15x14","4th Bedroom: 15x12"]}`

有人可以指出一些方法吗?我试过像fast-csv,csv-parse等等。但是无法将同一字段的值合并(推或附加)到一个字段中作为数组。 感谢。

我现在完成的代码:

var fs = require('fs');
var csv = require('fast-csv');
var stream = fs.createReadStream("../../HouseDataDev01.csv");
csv
.fromStream(stream, {columns:true, ignoreEmpty:true, headers : 
["price","bedrooms"]})
.on("data", function(data){
//      console.log(data);
})
.on("end", function(){
    console.log("done");
});

==========

我提出了一个想法,也许我可以创建一个对象

var NewHouse = require('../models/NewHouse.js'); 
//NewHouse is a schema I created before to store the csv data

var test = new NewHouse;

这样我就可以使用这样的测试对象:

.on("data", function(data){
        for(i in test){
            test.i.push(data[index];
        }

但我发现测试中有许多其他属性,如:$ __ reset,$ __ dirty,$ __ setSchema

我怎么能写这个循环?

1 个答案:

答案 0 :(得分:-1)

好的,让我解释一下......

我的解决方案的要点是创建一些像headtagfieldname{}来记录来自fs的流,它逐行读取csv。我使用headtag来验证流行的轮次。例如,对于第一轮,我需要行的值作为我最终json文件中每个对象的键。如果我在header方法中设置了fromStream(),那么每一轮的结果都会占据标题,我不知道如何“合并”它们,所以我选择了这种“棘手”的方式。

然后,就像我最后的json文件一样,某些(不是全部)字段将是数组。因此,当我读取第二个不是空字符串“”的值时,我应该将字段转换为数组。使用readResult[fieldnames[i]]=new Array( readResult[fieldnames[i]]);

这是代码:

//create a fime stream
var stream = fs.createReadStream(csvfilepath);

//as the file will be read row by row, headtag is pointer to row.
//e.g: headtag = 5, means the stream is reading the 5th row of the csv file
var headtag=0;

//the final stream read result, will be the same format in schema.
var readResult={};

//fieldname records the headers key name.
var fieldnames={};
csv.fromStream(stream,{ignoreEmpty:true})
    .on("data", function(data){
    if(headtag === 0){
        //I assume the first row is the headers,so should make sure the headers' names are the same in your schema
        fieldnames = data;
        for(var i=+0; i<data.length; i++){
        readResult["data[i]"] = {};
        }
    }
    if(headtag === 1){
        //some of fields may only conatins one value, so save them as a String
        for(var i=+0; i<data.length; i++){
        readResult[fieldnames[i]] = data[i];
        }
    }
    if(headtag === 2){
        for(var i=+0 ; i<data.length; i++){
        //for those field that may contains multiple values, convert them as an array, then push all values in it.
        if(data[i]!==""){
            readResult[fieldnames[i]]=new Array( readResult[fieldnames[i]]);
             readResult[fieldnames[i]].push(data[i]);
        }
        }
    }
    if(headtag > 2){
        for(var i=+0 ; i<data.length; i++){
                if(data[i]!==""){
                readResult[fieldnames[i]].push(data[i]);
                }
            }
    }
    headtag=headtag+1;
    })
    .on("end",function(){
    readResult.images = images;
    //create a time tag
    var startdate = moment().format('MM/DD/YYYY');
    var starttime = moment().format('H:mm:ss');
    readResult.save_date=startdate;
    readResult.save_time=starttime;
    //save the data in mongodb
    NewHouse.create(readResult, function(error, house){
        if(error){
        console.log(error);
        }
        else{
        console.log("successfully create a document in your mongodb collection!");
        }
    });
    });

在此问题的基础上,我更新了我的代码。现在,您可以同时阅读csv fileimages并将其保存到mongodb。

了解更多信息,请点击此处: https://github.com/LarryZhao0616/csv_to_json_converter