【问题标题】:Stringify data from a map?对地图中的数据进行字符串化?
【发布时间】:2019-07-20 23:16:07
【问题描述】:

最终目标是输入一个巨大的 txt 文件并替换 csv 文件中给出的所有单词。一个新的 txt 文件将与一个新的 csv 文件一起创建,该文件计算每个单词的出现次数。

我遇到的问题是将地图数据写入新的 csv 文件。我知道数据未定义,但如何将其更改为可读?

无论我在data.push字段中放入什么样的map.thingie,都会出错。

var fs = require('fs');
var inputFile='OneLetter.csv';
var parse = require('csv-parse');
var map1 = new Map();
var iterator = map1[Symbol.iterator]();


//This part creates a stream, essentially reads it and creates a list

var parser = parse({delimiter: ';'}, function (err, data) {
    data.forEach(function(line) {
      // create line object out of parsed fields
      var list = map1.set(line) 
     });
        for (let item of iterator) {
    console.log(item)
    };    
});

fs.createReadStream(inputFile).pipe(parser);


//This program writes a CSV file containing data in the data1, data2... fields

let data = [];
let columns = {
        Column1: '# times',
        Column2: 'Original',
        Column3: 'Short'
};

  data.push(['data1',
             'data2',
             'data3'
]); 

var stringify = require('csv-stringify');

stringify(data ,{ delimiter: ';', header: true, columns: columns }, (err, output) => {
  if (err) throw err;
  fs.writeFile('TEST.csv', output, (err) => {
    if (err) throw err;
    console.log('TEST.csv saved.');
  });
});

Working Result:

[ [ 'A', 'A' ], undefined ]
[ [ 'B', 'BE' ], undefined ]
[ [ 'C', 'SEE' ], undefined ]
[ [ 'D', 'IN THE' ], undefined ]
[ [ 'E', 'HE' ], undefined ]
[ [ 'F', 'OF THE' ], undefined ]
[ [ 'G', 'FROM THE' ], undefined ]
[ [ 'H', 'HAS' ], undefined ]
[ [ 'I', 'I' ], undefined ]
[ [ 'J', 'BY WHICH' ], undefined ]
[ [ 'K', 'OUT OF THE' ], undefined ]
[ [ 'L', 'ALL' ], undefined ]
[ [ 'M', 'MORE' ], undefined ]
[ [ 'N', 'NOT' ], undefined ]
[ [ 'O', 'OF' ], undefined ]
[ [ 'P', 'PER' ], undefined ]
[ [ 'Q', 'ON THE' ], undefined ]
[ [ 'R', 'ARE' ], undefined ]
[ [ 'S', 'SEPERATOR' ], undefined ]
[ [ 'T', 'THE' ], undefined ]
[ [ 'U', 'YOU' ], undefined ]
[ [ 'V', 'OF WHICH' ], undefined ]
[ [ 'W', 'WITH' ], undefined ]
[ [ 'X', 'IN WHICH' ], undefined ]
[ [ 'Y', 'YES' ], undefined ]
[ [ 'Z', 'FROM WHICH' ], undefined ]
TEST.csv saved.

非工作结果:

Error: Invalid Record: expect an array or an object, got undefined
    at Stringifier._transform (C:\Program Files\nodejs\node_modules\csv-stringify\lib\index.

【问题讨论】:

    标签: javascript node.js csv parsing dictionary


    【解决方案1】:

    根据文档,我似乎没有看到在 parse 方法中转换的选项 - 您需要尝试使用 transform 让它以您想要的方式工作 - 所以创建一个并传递它这个:

    const transformer = transform(function(data){
        return replaceEntries(data); // here you call the replacement
    });
    fs.createReadStream(textFile).pipe(parser).pipe(transformer).pipe(stringify);
    

    变压器需要提前准备

    从您的情况来看,似乎没有记录传递转换函数,并且错误可能来自那个......此外,您的代码似乎没有做您想要实现的目标,更像是您正在尝试创建新的 CSV。

    我认为你可能从一个奇怪的角度开始了这项任务,所以我建议你从头开始重做 - 你需要编写一个按以下顺序执行以下操作的程序:

    1. 将 CSV 文件读入内存并创建一个映射或替换数组
    2. 从 TXT 文件创建可读流
    3. 创建一个转换流并将可读的管道传输给它
    4. 创建一个可写流并将转换通过管道传递给它

    我还可以建议使用我创建的scramjet 框架,这可能会使代码更容易理解:

    const {StringStream} = require("scramjet");
    
    StringStream
        // here we read the file
        .from(fs.createReadStream('massive.txt'))
        .use(async stream => {
            // here we create replacements
            const replacements = await (
                StringStream.from(fs.createReadStream('massive.txt'))
                    .csvParse({header: false})
                    // the line below will make sure we're replacing whole words
                    .map(([_from, _to]) => ([new RegExp(`\b${_from}\b`, "g"), _to])
                    .toArray()
            );
    
            // here we map all the items in the stream and iterate over all the replacements
            return stream.map(
                chunk => replacements.reduce((s, [_from, _to]) => s.replace(_from, _to), chunk)
            );
        })
        // and here we push the replaced stream to the output file
        .pipe(fs.createWriteStream('massive-file-out.txt');
    

    请检查以.map(([_from, _to]) => 开头的行。我假设您只想替换整个单词的文本,所以更多R U ready -> Are you ready,而不是Robert -> Areobert - 这就是这一行的目的。

    【讨论】:

    • 对不起,我不知道如何正确使用这段代码。了解 ([new RegExp(\b${_from}\b, "g"), _to]) 的作用可能会有所帮助。此外,在地图数据没有作为单独的键/值加载之前,但我现在修复了它。我没有在上面的代码中读到它从先前创建的地图中获取键/值的任何地方,而是创建了一个新地图。你也错过了一些)在这里和那里,我修复了。
    • 我将在 github 上创建一个 repo 并发布工作示例。至于 RegExp - 这是一个匹配整个单词的正则表达式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 2015-07-06
    • 2014-02-20
    • 1970-01-01
    • 2016-11-07
    相关资源
    最近更新 更多