我有多个 csv 格式的文件
- 模型1A
- 模型1B
- 模型2A
- 模型2B
其中每个 csv 都是一个数组,即 model1A = [1, 1, 1]
我想解析这些 csvs 并创建一个包含所有这些模型的数组,其中数组中的每个元素都是对应于一个特定模型的对象,即
finalArray = [
{
"model" : "model1",
"A" : [1, 1, 1],
"B" : [2, 2, 2]
},
{
"model" : "model2",
"A" : [3, 3, 3],
"B" : [4, 4, 4]
}
]
我目前的代码是
var csv = require('csv');
var fs = require('fs');
var parser = csv.parse();
var util = require('util');
var junk = require('junk');
var _ = require('lodash');
var models = [];
fs.readdir(__dirname+'/data', function(err, files) {
var model = {};
_.forEach(files, function(n, key) {
console.log('Analysing file: ' + n);
var modelName;
var modelNum;
var modelParam;
modelNum = n.match(/\d+/)[0];
modelName = 'model' + modelNum;
modelParam = (n.substring(0, n.indexOf('.'))).replace(modelName,'');
model.model = modelName;
model[modelParam] = [];
models.push(model);
//if (Object.keys(model).length === 3) {
// models.push(model);
// model = {};
//}
fs.createReadStream(__dirname+'/data/'+n).pipe(csv.parse()).pipe(csv.transform(function(row) {
model[modelParam].push(row);
})).on('readable', function(){
while(this.read()){}
}).on('end', function() {
console.log('finished reading file ' + n);
if (key === (files.length - 1)) {
fs.writeFile('result.json', JSON.stringify(models), function (err) {
if (err) throw err;
console.log(models.length + ' model(s) parsed');
console.log('done');
});
}
}).on('error', function(error) {
console.log(error);
});
});
});
我知道我的一个问题是我很快就会将模型推送到数组中,从而产生下面形式的最终数组,其中 model1
被 model2
[ { model: 'model2', A: [], B: [] },
{ model: 'model2', A: [], B: [] },
{ model: 'model2', A: [], B: [] },
{ model: 'model2', A: [], B: [] } ]
这就是我尝试这段代码的原因
if (Object.keys(model).length === 3) {
models.push(model);
model = {};
}
但这当然行不通,因为 fs.createReadStream
是异步的,我正在用 model = {}
清除模型,然后才能正常运行。
我现在处于这样一个阶段,我觉得我在兜圈子,只会让事情变得更糟。我想创建一些更通用的东西,但是,现在我很高兴让它适用于这里介绍的案例,然后我可以考虑改进它。
任何帮助将不胜感激!
更新 1
按照 saquib khan 的建议,将 var model = {}
移动到循环内,这帮助我更接近我的目标,但它仍然不正确。下面是目前的结果
[
{
"model": "model1",
"A": [
[
"1"
],
[
"2"
],
[
"3"
],
[
"4"
]
]
},
{
"model": "model1",
"B": [
[
"1"
],
[
"2"
],
[
"3"
],
[
"4"
]
]
},
{
"model": "model2",
"A": [
[
"1"
],
[
"2"
],
[
"3"
],
[
"4"
]
]
},
{
"model": "model2",
"B": [
[
"1"
],
[
"2"
],
[
"3"
],
[
"4"
]
]
}
]
更新 2
同样遵循 Denys Denysiuk 的建议,结果更接近我想要的,但仍然很短
[
{
"model": "model1",
"A": [
"1",
"2",
"3",
"4"
]
},
{
"model": "model1",
"B": [
"1",
"2",
"3",
"4"
]
},
{
"model": "model2",
"A": [
"1",
"2",
"3",
"4"
]
},
{
"model": "model2",
"B": [
"1",
"2",
"3",
"4"
]
}
]
如果我能以某种方式迭代最终的对象数组,合并具有匹配 model
名称的对象,这将起作用。我目前正在浏览 lodash docs看看我能不能弄清楚。如果有的话,我会在这里发帖。
最佳答案
您的代码中有一个很小的编码错误。
var model = {}; 应该在 forEach 循环内。
试试下面的代码:
var csv = require('csv');
var fs = require('fs');
var parser = csv.parse();
var util = require('util');
var junk = require('junk');
var _ = require('lodash');
var models = [];
fs.readdir(__dirname+'/data', function(err, files) {
_.forEach(files, function(n, key) {
console.log('Analysing file: ' + n);
var model = {};
var modelName;
var modelNum;
var modelParam;
modelNum = n.match(/\d+/)[0];
modelName = 'model' + modelNum;
modelParam = (n.substring(0, n.indexOf('.'))).replace(modelName,'');
model.model = modelName;
model[modelParam] = [];
models.push(model);
//if (Object.keys(model).length === 3) {
// models.push(model);
// model = {};
//}
fs.createReadStream(__dirname+'/data/'+n).pipe(csv.parse()).pipe(csv.transform(function(row) {
model[modelParam].push(row);
})).on('readable', function(){
while(this.read()){}
}).on('end', function() {
console.log('finished reading file ' + n);
if (key === (files.length - 1)) {
fs.writeFile('result.json', JSON.stringify(models), function (err) {
if (err) throw err;
console.log(models.length + ' model(s) parsed');
console.log('done');
});
}
}).on('error', function(error) {
console.log(error);
});
});
});
关于javascript - 从 Node 中解析的 csv 文件构建对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30752919/