背景
先說說為什么要弄什么行轉列。
| 時間 | 類別 | 費用 | 
| 2014-07-08 | 電費 | 120 | 
| 2014-07-08 | 水費 | 23 | 
| 2014-07-09 | 電費 | 44 | 
| 2014-07-09 | 水費 | 77 | 
| 2014-07-10 | 電費 | 45 | 
| 2014-07-10 | 水費 | 21 | 
| 2014-07-11 | 電費 | 34 | 
| 2014-07-11 | 水費 | 27 | 
費勁的弄出表格,才發現,弄成了每天的水電費,不過是測試數據,不要在意這些細節。
很多時候我們就通過sql語句在數據庫中查詢到如上數據,那么展現到頁面的時候,勢必要變成下面一種格式
| 時間 | 電費 | 水費 | 
| 2014-07-08 | 120 | 23 | 
| 2014-07-08 | 44 | 77 | 
| 2014-07-09 | 45 | 66 | 
| 2014-07-09 | 43 | 77 | 
| 2014-07-10 | 21 | 45 | 
| 2014-07-10 | 54 | 21 | 
| 2014-07-11 | 65 | 34 | 
| 2014-07-11 | 65 | 27 | 
那我們循環來生成table的html吧。
有些善於提問的朋友可能會問到,既然要這樣顯示,那么可以把電費和水費作為列存儲在table中啊。這里不多討論這個話題,因為中國的收費越來越多,物業費、保護費、稅收、天然氣等等各種名目......
因此才希望無論費用類別有多少種,都能把它自動轉換成列名信息,以表格形式呈現在用戶面前。
實現
實現起來很簡單,指定主鍵字段,用來作為列名的字段,值字段,對應上面的實例依次為 "時間",“類別”,"費用"。
主要思路則是,遍歷JSON,取到每一行的類別的值,作為列名存儲。
這里增加了一個默認值,意在解決數據不完整的問題。
再次用下上面的實例,正確的做法是每天都會對水表和電表進行抄表計算費用,那么萬一哪天沒寫怎么辦,那轉換后該結構不是不完整了嗎,比如2014-07-09號只有電費,連水費這一行數據都沒有,因此在轉換成功后,特意檢測了是否存在這樣的情況,如果存在,則設置默認值。
/* json數據行列轉換 * @jsonData json數據源 * @idField 條件字段 * @colField 生成列名的字段 * @valueField 生成值的字段 * @emptyValue 默認值 避免有些數據不全 */ function row2col(jsonData, idField, colField, valueField, emptyValue) { var result = [], //存儲返回的數據 idIndexData = {},//存儲id在數組中的信息(位置) resultColumns = {},//存儲列名數據 curRecord = null;//存儲當前數據 var colFields = colField.split(','); // // 循環整個JSON數組:[{...},{...},{...},...] for (var idx = 0; idx < jsonData.length; idx++) { //當前json數據對象 var cdata = jsonData[idx]; //根據主鍵值,查找到結果數組中的索引號 var idValue = cdata[idField]; var num = idIndexData[idValue];//獲取存儲該id的數組索引號 if (num != null) { curRecord = result[num]; } else { //初始化數據時保持完整的結構信息 避免因為缺乏數據,缺乏指定的列數據 curRecord = {}; } // 指定的colFields列下的數據作為y軸,則取出該列的數據作為y軸即可 for (var i in colFields) { var key = colFields[i]; //獲取到colField的值,作為列名 var value = cdata[valueField]; curRecord[value] = cdata[key]; //存儲列名 resultColumns[value] = null; break; } //除數據內容外,還需要添加主鍵數據 curRecord[idField] = idValue; //對象若為新建 則新增進數組 if (num == null) { idIndexData[idValue] = result.push(curRecord) - 1; } } //數據檢查 由於是將行數據作為列名,則可能會存在部分行缺少其他列數據,若缺少,則指定默認值 for (var i in result) { for (var name in resultColumns) { if (!result[i].hasOwnProperty(name)) result[i][name] = emptyValue; } } return result; }
