nodejs數據處理實踐之數據預處理

任務描述:

有一個csv文件, 可是其中某些行的字段的值是一個json數組,數組的值又是json對象,內部有不少','html

這致使,在其它的數據分析工具中,沒法進行處理。node

如今咱們但願,把這個json數組拆分開來,取出內部的值,而後對於字段值不是json的則補空位,造成一個比較規整的表格。遍歷於後面分析。es6

最好的語言,是熟悉的語言。json

因此我用了js,固然由於是處理文件,因此確定是nodejs.api

不過熟悉是相對的,真正開始仍是要靠google。數組

思路

大概的思路就是,使用readline模塊,逐行讀取文件,而後對於每一行,首先使用split(,)切分開來,而後對數組的長度進行判斷,數組長度超過規定值的,就是內部包含json數組的,由於json數組的位置,老是在第3個到導數第2個之間,使用slice()函數,提取出來。而後把這個不規整的數組,用join()拼成json字符串,再解析出數組,提取出值,寫回去,對於正常的行,則使用一個固定的模式填補。函數

代碼

const readline = require('readline');
const fs = require('fs');
const os = require('os')

let inputName = process.argv[2] || 'xxx.csv' // 輸入文件
let outputName = process.argv[3] || 'parse3 .csv' // 輸出文件

const reader = fs.createReadStream(inputName);
const writer = fs.createWriteStream(outputName);
const rl = readline.createInterface({
    input: reader,
    output: writer
});


let lineNum = 0;
let 沒用的數 = 0;
let padArray = ['null', 0, 'null', 0, 'null', 0]


rl.on('line', (line) => {
    if (lineNum == 0) {
        lineNum++;
        return; // 跳過行頭
    }

   
    let arr = line.split(',');
   
    if (arr.length > 5) {
        // 特殊狀況,含有json數組
        let midArrRaw = arr.splice(3, arr.length - 4); // 取出json數組部分
        
        let json = midArrRaw.join(','); // 拼成json字符串

        let midArr = JSON.parse(json); // 解析json
        let newMidArr = []
        for (let i = 0; i < midArr.length; i++) {
            let obj = midArr[i]
          
            for(let key in obj) {
                newMidArr.push(obj[key]) // 遍歷,解析出對象中的值, 這裏不保險,由於 for in 不保證順序,不過在這裏沒有問題
            }
        }
        if (newMidArr.length !== 6) {
            console.log(newMidArr)
            throw new Error('error ' + lineNum + midArr) // 異常終止, 解析出來的數組長度應爲6
        }
        
        arr.splice(3, 0, ...newMidArr); // 把數組插入到第3個位置。 ...是es6語法,把數組擴展開
        
    } else {
        arr.splice(3, 1, ...padArray); // 正常狀況, 把補位數組插入
    }

    writer.write(arr.join(',') + os.EOL) // 輸出, 這裏用','分割,若是','不行也能夠換別的,csv文件不必定要用','分割
    
    沒用的數++;
    if (沒用的數 == 10000) {
        console.log(lineNum) // 輸出一下進度
        沒用的數=0
    }
    

    lineNum++;

});

// close事件監聽
rl.on("close", function () {
    // 結束程序    
    console.log(lineNum)
});

總結

使用工具

require('os').EOL

來獲得操做系統範化的換行符。ui

令我疑問的是,不知道爲何不能夠直接利用readline模塊輸出。google

參考文獻:

  1. 【node.js】'readline' 逐行讀取、寫入文件內容

  2. nodejs readline

  3. nodejs中如何按行讀取文件?

相關文章
相關標籤/搜索