我尝试通过解析器管道CSV文件,删除给定ID的行,将新数组传输到字符串,然后最终将结果输出到新的CSV。
问题是新数组未正确返回。我的意思是,我设法删除该行但不返回新的CSV。
以下是CSV file
以下是代码:
'use strict';
const Fs = require('fs');
const Csv = require('csv');
let input = 'data_stack.csv';
let output = 'data_output.csv';
let readStream = Fs.createReadStream(input);
let writeStream = Fs.createWriteStream(output);
let opt = {delimiter: ',', quote: '"', escape: '"', relax: true, skip_empty_lines: true};
function deleteRow (id) {
return Csv.parse(opt, (err, data) => {
if (err) throw err;
let delId = [];
// The row corresponding to the id is pushed to an array to console.log it. The other rows are returned
let newData = data.filter(line => {
if (line[0] === id) {
delId.push(line);
}
else {
return line;
}
});
if (delId !== 0) {
console.log("Deleted line\n");
console.log(delId);
}
// Testing if the row was deleted
let result = [];
// If the row is not deleted, push it into the result array
newData.forEach(line => {
if (line[0] === id) {
result.push(line);
}
});
// "Not found !" is console logged. The row has been deleted
if (result.length !== 0) {
console.log(result);
}
else {
console.log("Not found !");
}
return newData;
});
}
readStream.pipe(deleteRow('566150121ae803f53751c3f2'))
此代码正常运行 但是如果我选择返回newData数组来管道一个字符串,然后将结果输出到CSV文件,我会得到2个意外的行为:
以下是代码:
'use strict';
const Fs = require('fs');
const Csv = require('csv');
let input = 'data_stack.csv';
let output = 'data_output.csv';
let readStream = Fs.createReadStream(input);
let writeStream = Fs.createWriteStream(output);
let opt = {delimiter: ',', quote: '"', escape: '"', relax: true, skip_empty_lines: true};
function deleteRow (id) {
return Csv.parse(opt, (err, data) => {
if (err) throw err;
let delId = [];
// The row corresponding to the id is pushed to an array to console.log it. The other rows are returned
let newData = data.filter(line => {
if (line[0] === id) {
delId.push(line);
}
else {
return line;
}
});
if (delId !== 0) {
console.log("Deleted line\n");
console.log(delId);
}
// Testing if the row was deleted
let result = [];
// If the row is not deleted, push it into the result array
newData.forEach(line => {
if (line[0] === id) {
result.push(line);
}
});
// "Not found !" is console logged. The row has been deleted
if (result.length !== 0) {
console.log(result);
}
else {
console.log("Not found !");
}
return newData;
});
}
let stringifier = Csv.stringify({quoted: true});
readStream.pipe(deleteRow('566150121ae803f53751c3f2')).pipe(stringifier).pipe(writeStream);
我真的不明白来自deleteRow函数的结果如何影响它的行为。
有任何建议吗?
答案 0 :(得分:0)
csv.parse
有2 APIs:
如果您传递回调函数,就像您在示例中所做的那样,您正在订阅回调API,这意味着您可以通过data
参数获得整个解析后的数据。
但是,该回调是一个流'sink',这意味着对数据的任何修改都不会归结为writeStream
。
您需要调整代码以使用回调API,如下所示:
function deleteRow(readStream, id, done) {
readStream.pipe(Csv.parse(opt, (err, data) => {
if (err) return done(err);
// Wrire new data to file
Csv.stringify(data.filter(line => line[0] !== id))
.pipe(writeStream)
.on('end', done);
}));
}
deleteRow(readStream, '5660d7e11ae803f53751aeb0', function (err) {
console.log('done!');
});
或者,使用像这样的流API: