用javascript编写数百万行csv的最佳方法

用javascript编写数百万行csv的最佳方法,javascript,node.js,csv,Javascript,Node.js,Csv,我有一个巨大的数组,大约有1000万个对象,每个对象有11个不同的键和值对 将阵列内容写入csv的最佳方式是什么 我尝试使用csv writer和快速csv- 使用csv编写器 fastcsv .write(final, { headers: true }) .pipe(ws); 使用快速csv csvWriter.writeRecords(final) .then(() => { console.log('...Writing csv Done. Che

我有一个巨大的数组,大约有1000万个对象,每个对象有11个不同的键和值对

将阵列内容写入csv的最佳方式是什么

我尝试使用csv writer和快速csv-

使用csv编写器

fastcsv  
  .write(final, { headers: true })
  .pipe(ws);
使用快速csv

csvWriter.writeRecords(final)
    .then(() => {
      console.log('...Writing csv Done. Check CSV');
    });
这两种方法都会导致字符串长度无效

.join(记录分隔符)+记录分隔符; ^

RangeError:字符串长度无效 at Array.join(本机)

示例对象如下所示

{ distance: 0.14,
a_id: 1923,
long: -122.234,
lat: 47.631,
DPlong: -122.234,
DPlat: 47.632,
class: 'secondary',
way_id: 2,
timestamp: '5-6-2017',
user: 'hello',
code: 'DS' }

解决这个问题的最好办法是什么?任何帮助都将不胜感激。谢谢。

您不能将整个数组转换为字符串,因为字符串太长,无法为js处理,您必须将其分块格式化:

const tick = () => new Promise(res => setTimeout(res, 0));

const toRow = obj =>
  obj.distance + "," +
  obj.a_id + "," + 
  obj.long + "," +
  obj.lat + "," +
  obj.DPlong + "," +
  obj.DPlat + "," +
  obj.class + "," +
  obj.way_id + "," + 
  obj.timestamp + "," + 
  obj.user + "," + 
  obj.code;

const formatChunk = array => array.map(toRow).join("\n") + "\n";

const size = 1000; // <- experiment with it
(async function() {
  for(let i = 0; i < final.length; i += size) {
    ws.write(formatChunk(final.slice(i, i + size)));
    await tick();
  }
  ws.end();
})();
const tick=()=>newpromise(res=>setTimeout(res,0));
常数toRow=obj=>
目标距离+“,”+
obj.a_id+,“+
obj.long+“,”+
obj.lat+“,”+
obj.DPlong+“,”+
obj.DPlat+“,”+
对象类+“,”+
obj.way_id+“,”+
obj.timestamp+“,”+
obj.user+“,”+
obj代码;
const formatChunk=array=>array.map(toRow.join)(“\n”)+“\n”;
常数大小=1000;// 伪java代码:

open file
for(var i = 0; i < array.length; i++){
  writeline('distance,' + array[i].distance + ... )
}
close file
打开文件
对于(var i=0;i
如果字符串长度是一个问题,使用csv writer,您可以发出多个
writeRecords
调用,而不是一个调用

const BATCH\u SIZE=10000;
const batchNumber=数学单元(最终长度/批次大小);
[…数组(批次号)]。减少(
(承诺,_值,i)=>{
常量子数组=最终切片(批次大小*i,批次大小*(i+1));
返回promise.then(()=>csvWriter.writeRecords(子数组));
},
承诺,决心
);
但是,如果您不需要预先构建1000万个对象阵列并通过节点流获取它们,那么有一种更具可伸缩性的方法


回答太晚了,但对于需要优化的、耗时更少的解决方案的人来说 以上所有的解决方案都是好的,但都有缺陷

  • 时间复杂度O(n)
  • 高存储复杂性O(n)或高内存使用问题有时应用程序可能会 由于请求太多而崩溃
  • 解决方案:当用户对数据库执行CRUD操作(例如在put请求中)时,维护一个同步的CSV文件

    app.put('/product/:id', (res,req)=>{
        // step 1 do update operation in db
        // step 2 do update operation in CSV file
    
        return res.send('OK 200')
    
    })
    
    所以下次当用户请求CSV时,用户可以立即获得CSV文件


    快乐编码:)

    手写。不要使用库。哇,这是我见过的第一个超过最大可能字符串长度的情况。@DanielA.White是对的。你自己写,一行一行地写,你永远不会超过字符串的能力。@Jonaswillms执行这类操作的字符串长度的最大限制是多少?类似于写入csv。@csvb数组和字符串索引必须是整数,JS数字最多可以用作2**53-1的整数,因此数组的最大长度可以是2**53(0也是有效索引)