需求: 師弟讓我幫他處理一個數據,是一個降雨數據,從2015.1.號到2016.12.31號收集的某地區的降雨數據,一共105000條數據,數據格式爲csv格式,第一列爲編號,第二列爲時間,第三列爲該時刻的降雨量,數據特徵是若是某段時間的先後都有36個0,則說明這段時間內爲一場降雨,咱們要作的是求一場降雨的起始時刻以及降雨總量。javascript
初次看到數據的時候感受思路挺清晰的,後來寫的時候發現到處是坑,好多細節須要注意到。先列出採坑記錄:java
我用數組的時候取值和賦值直接經過下標來實現,後來發現這樣仍是不行滴,不說常常會出現問題,從寫代碼的優雅感角度來講這是一種粗暴的方式,因此仍是須要一種優雅的方式———定義構造函數json
function Dictionary(){
this.data = new Array();
this.put = function(key,value){
this.data[key] = value;
};
this.get = function(key){
return this.data[key];
};
this.size = function(){
return this.data.length;
};
}
複製代碼
對於下面的數據應該怎麼取值,開始我是result[0][0].start
來獲取start的值,可是發現這種方式是錯誤的,正確的方式應該是result[0].start
,即這樣理解:result是一個一維數組,而不是二維數組,數組的每一個元素是一個json元素數組
var result=[ [ start: '201501131150',
end: '201501140950',
sum: 15.599999999999984 ],
[ start: '201501250430',
end: '201501250910',
sum: 1.4000000000000004 ],
[ start: '201501262230',
end: '201501270330',
sum: 1.2000000000000002 ],
[ start: '201501271320',
end: '201501272050',
sum: 1.0999999999999999 ],
[ start: '201501281030',
end: '201501290050',
sum: 2.800000000000001 ]
]
複製代碼
因此個人理解是上面的result與下面的result等價編輯器
var result=[ { start: '201501131150',
end: '201501140950',
sum: 15.599999999999984 },
{ start: '201501250430',
end: '201501250910',
sum: 1.4000000000000004 },
{ start: '201501262230',
end: '201501270330',
sum: 1.2000000000000002 },
{start: '201501271320',
end: '201501272050',
sum: 1.0999999999999999 },
{ start: '201501281030',
end: '201501290050',
sum: 2.800000000000001 }
]
複製代碼
文件的讀寫操做,想把最後的結果相似上面的result格式寫入到TXT文件中,剛開始用fs.writeFile方法,發現怎麼寫都不行,即時把result轉換成字符串再寫入都不行,要麼獲取到空的數組,要麼獲取到的全是逗號。後來想到:用循環來作吧,每次將數組裏的一個json對象輸出到TXT文件,注意這裏用Buffer轉換每次的數成二進制的再寫入到文件中函數
var chunks=[];
var length=0;
result.forEach((item,index)=>{
var start=item.start;
var end=item.end;
var sum=item.sum;
var value=start+" "+end+" "+sum+" "+'\r\n';
var buffer=new Buffer(value);
chunks.push(buffer);
length+=buffer.length;
})
var resultBuffer = new Buffer(length);
for(var i=0,size=chunks.length,pos=0;i<size;i++){
chunks[i].copy(resultBuffer,pos);
pos+=chunks[i].length;
}
fs.writeFile('./result.txt',resultBuffer,function(err){
if(err) throw err;
console.log('write JSON into TEXT');
});
複製代碼
有一個問題要考慮的是若是一場降雨前面0的個數大於36的話,那麼這隻能算做一場降雨,若是不加其餘約束條件的話前面有38個0的時候會算成3場雨的,因此咱們須要當前面已經連續36個零的時候第第37個數不能爲零(原諒我直接這麼暴力的寫,由於36個真的不算太多)ui
if (data[i][1] == 0 && data[i + 1][1] == 0 && data[i + 2][1] == 0 && data[i + 3][1] == 0 && data[i + 4][1] == 0 && data[i + 5][1] == 0&&
data[i+6][1] == 0 && data[i + 7][1] == 0 && data[i + 8][1] == 0 && data[i + 9][1] == 0 && data[i + 10][1] == 0 && data[i +11][1] == 0&&
data[i+12][1] == 0 && data[i + 13][1] == 0 && data[i + 14][1] == 0 && data[i + 15][1] == 0 && data[i + 16][1] == 0 && data[i + 17][1] == 0&&
data[i+18][1] == 0 && data[i + 19][1] == 0 && data[i + 20][1] == 0 && data[i + 21][1] == 0 && data[i + 22][1] == 0 && data[i + 23][1] == 0&&
data[i+24][1] == 0 && data[i + 25][1] == 0 && data[i + 26][1] == 0 && data[i + 27][1] == 0 && data[i + 28][1] == 0 && data[i + 29][1] == 0&&
data[i+30][1] == 0 && data[i + 31][1] == 0 && data[i + 32][1] == 0 && data[i + 33][1] == 0 && data[i + 34][1] == 0 && data[i + 35][1] == 0&&
data[i+36][1]!=0)
複製代碼
還有一個問題是若是到了數據的最後一個數時就不用判斷後面還要36個0了,只須要判斷前面有36個零就ok了,因此這裏也要考慮到這個狀況this
if ((data[j][1] == 0 && data[j + 1][1] == 0 && data[j + 2][1] == 0 && data[j + 3][1] == 0 && data[j + 4][1] == 0 && data[j + 5][1] == 0&&
data[j+6][1] == 0 && data[j + 7][1] == 0 && data[j+ 8][1] == 0 && data[j + 9][1] == 0 && data[j + 10][1] == 0 && data[j +11][1] == 0&&
data[j+12][1] == 0 && data[j + 13][1] == 0 && data[j+ 14][1] == 0 && data[j + 15][1] == 0 && data[j + 16][1] == 0 && data[j + 17][1] == 0&&
data[j+18][1] == 0 && data[j + 19][1] == 0 && data[j + 20][1] == 0 && data[j+ 21][1] == 0 && data[j + 22][1] == 0 && data[j + 23][1] == 0&&
data[j+24][1] == 0 && data[j + 25][1] == 0 && data[j + 26][1] == 0 && data[j + 27][1] == 0 && data[j + 28][1] == 0 && data[j + 29][1] == 0&&
data[j+30][1] == 0 && data[j + 31][1] == 0 && data[j + 32][1] == 0 && data[j + 33][1] == 0 && data[j + 34][1] == 0 && data[j + 35][1] == 0)
||j==data.length-1 )
複製代碼
最後要注意的是寫入到TXT文件中時字符串後面加上「\r\n"才能換行,這樣咱們直接點開TXT文件看到的纔是通過換行的數據,若是是在字符串後面加上」\n"那麼咱們用編輯器打開TXT文件確實看到的也是換行後的數據,可是這時直接打開TXT文件看到的數據並無換行,因此這點也要注意spa
var value=start+" "+end+" "+sum+" "+'\r\n';
複製代碼
最後咱們來看看獲得的結果txt文件,大功告成!3d
源碼:
var fs = require("fs");
fs.readFile('./test.csv', function (err, data) {
var table = new Array();
if (err) {
console.log(err.stack);
return;
}
ConvertToTable(data, function (table) {
var cont=[];
var result=[]
transform(table,cont);
console.log("**************************************************")
cont.forEach((item,index)=>{
result[index]=item.data;
})
console.log(result)
var chunks=[];
var length=0;
result.forEach((item,index)=>{
var start=item.start;
var end=item.end;
var sum=item.sum;
var value=start+" "+end+" "+sum+" "+'\r\n';
var buffer=new Buffer(value);
chunks.push(buffer);
length+=buffer.length;
})
var resultBuffer = new Buffer(length);
for(var i=0,size=chunks.length,pos=0;i<size;i++){
chunks[i].copy(resultBuffer,pos);
pos+=chunks[i].length;
}
fs.writeFile('./result.txt',resultBuffer,function(err){
if(err) throw err;
console.log('write JSON into TEXT');
});
console.log("程序執行完畢");
})
})
function ConvertToTable(data, callBack) {
data = data.toString();
var table = new Array();
var rows = new Array();
rows = data.split("\r\n");
for (var i = 0; i < rows.length; i++) {
table.push(rows[i].split(","));
}
callBack(table);
}
function transform(data,cont) {
var k = 0;
for (var i = 0; i < data.length; i++) {
var list = new Dictionary();
if (data[i][1] == 0 && data[i + 1][1] == 0 && data[i + 2][1] == 0 && data[i + 3][1] == 0 && data[i + 4][1] == 0 && data[i + 5][1] == 0&&
data[i+6][1] == 0 && data[i + 7][1] == 0 && data[i + 8][1] == 0 && data[i + 9][1] == 0 && data[i + 10][1] == 0 && data[i +11][1] == 0&&
data[i+12][1] == 0 && data[i + 13][1] == 0 && data[i + 14][1] == 0 && data[i + 15][1] == 0 && data[i + 16][1] == 0 && data[i + 17][1] == 0&&
data[i+18][1] == 0 && data[i + 19][1] == 0 && data[i + 20][1] == 0 && data[i + 21][1] == 0 && data[i + 22][1] == 0 && data[i + 23][1] == 0&&
data[i+24][1] == 0 && data[i + 25][1] == 0 && data[i + 26][1] == 0 && data[i + 27][1] == 0 && data[i + 28][1] == 0 && data[i + 29][1] == 0&&
data[i+30][1] == 0 && data[i + 31][1] == 0 && data[i + 32][1] == 0 && data[i + 33][1] == 0 && data[i + 34][1] == 0 && data[i + 35][1] == 0&&
data[i+36][1]!=0) {
if((i+37)<=data.length) {
for (var j = (i + 37); j <data.length; j++) {
if ((data[j][1] == 0 && data[j + 1][1] == 0 && data[j + 2][1] == 0 && data[j + 3][1] == 0 && data[j + 4][1] == 0 && data[j + 5][1] == 0&&
data[j+6][1] == 0 && data[j + 7][1] == 0 && data[j+ 8][1] == 0 && data[j + 9][1] == 0 && data[j + 10][1] == 0 && data[j +11][1] == 0&&
data[j+12][1] == 0 && data[j + 13][1] == 0 && data[j+ 14][1] == 0 && data[j + 15][1] == 0 && data[j + 16][1] == 0 && data[j + 17][1] == 0&&
data[j+18][1] == 0 && data[j + 19][1] == 0 && data[j + 20][1] == 0 && data[j+ 21][1] == 0 && data[j + 22][1] == 0 && data[j + 23][1] == 0&&
data[j+24][1] == 0 && data[j + 25][1] == 0 && data[j + 26][1] == 0 && data[j + 27][1] == 0 && data[j + 28][1] == 0 && data[j + 29][1] == 0&&
data[j+30][1] == 0 && data[j + 31][1] == 0 && data[j + 32][1] == 0 && data[j + 33][1] == 0 && data[j + 34][1] == 0 && data[j + 35][1] == 0)
||j==data.length-1 ){
list.put("start", data[i + 36][0]);
list.put("end", data[j - 1][0]);
var temp = 0;
for (var n = i + 36; n <= j - 1; n++) {
temp = temp + Number(data[n][1]);
}
list.put("sum", temp);
break;
}
}
cont[k++] = list;
}
}
}
}
function Dictionary(){
this.data = new Array();
this.put = function(key,value){
this.data[key] = value;
};
this.get = function(key){
return this.data[key];
};
this.size = function(){
return this.data.length;
};
}
複製代碼