2014-10-31 75 views
2

我對JavaScript很新穎。目前我的數據是CSV格式:以Javascript重新排列數據

place, time, value 
a, 2009, 25 
b, 2009, 35 
c, 2009, 14 
a, 2010, 42 
b, 2010, 13 
etc. 

我想在格式[{'place': 'a', 'data':[{'t': '2009', 'v': '25'}, {'t': '2010' etc.安排數據,所以我可以做一些線圖中D3

我目前使用下面的代碼。不過,我覺得這樣做效率不高,因爲如果我有相當數量的數據(40年以上的30個地方),JavaScript將遍歷所有數據30次。我還有其他方法可以解決這個問題嗎?

var instlist = [{'place': 'a', 'data':[]}, {'place':'b', 'data':[]}]; 
var data = instlist; 

for (var i = 0; i < placelist.length; i++){ 
for (var j = 0; j < rawData.length; j++){ 
    if (rawData[j]['place'] == instlist[i]['place']) { 
     data[i]['data'].push({'t': rawData[j]['t'],'v': rawData[j]['v']}) 
     } 
    } 
} 

謝謝。歡呼聲

+0

嗨。你的'rawData'數組是什麼樣的?是這樣的:'rawData = [{'place':'a | b | ...','data':{'t':...,'v':...}},{'放置':'a | b | ...','data':{'t':...,'v':...}},...]' – 2014-10-31 16:38:50

+0

這實際上看起來不那麼糟糕。有一件事,我會在循環前將'placelist.length'和'rawData.length'存儲在變量中,否則它們將在每次迭代時重新計算。 – 2014-10-31 16:41:23

+0

如果你的數據總是這樣,你可以使用一些庫,如https://lodash.com/來解析和存儲幫助程序。如果你來自MVC PHP或有LINQ積壓,一切都會很容易理解。 @ Andy的回答很好。 – 2014-10-31 16:47:42

回答

3

由於它是一個D3問題,D3-溶液簡潔。如果您有單獨的CSV文件,則可以使用d3.csv來加載它。第一

var csvString = [ 
 
    'place,time,value', 
 
    'a,2009,25', 
 
    'b,2009,35', 
 
    'c,2009,14', 
 
    'a,2010,42', 
 
    'b,2010,13' 
 
].join('\n'); 
 

 
var rows = d3.csv.parse(csvString); 
 
var data = d3.nest() 
 
    .key(function(d) 
 
    { 
 
    return d.place; 
 
    }) 
 
    .entries(rows); 
 

 
console.log(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

+0

出於興趣,這是否提供了OP想要的輸出:'[{'place':'a','data':[{'t':'2009','v':'25'}'或don你認爲這是必要的嗎? – Andy 2014-10-31 17:10:51

+0

@安迪首先,他告訴他是初學者。其次,這是一個D3問題。所以我確定他想把''''鍵重命名爲'''''鍵,因爲它是圖書館做它的方式。並測量代碼維護成本,我會做同樣的事情。 – saaj 2014-10-31 17:18:19

+0

@saaj感謝您參考d3。我認爲這正是我想要的,但是我無法將它與'd3.csv'結合起來。我使用var行; d3.csv('testcsv2.csv',function(error,input)rows = input;})'然後繼續'var data = d3.nest()',它告訴我該數組未定義。有什麼建議麼? – As3adTintin 2014-10-31 18:36:23

0

這只是使用一個循環。它沿着回車符將CSV分成strArr並創建一個新的輸出數組。然後它從元素1遍歷strArr到數組的長度(即從標籤之後),通過逗號將剩餘的元素拆分成一個新數組,並將每個新對象推送到輸出數組。

var strArr = str.split('\n'); 
var out = []; 
for (var i = 1, l = strArr.length; i < l; i++) { 
    var elems = strArr[i].split(','); 
    out.push({ 
    place: elems[0], 
    data: [{ t: elems[1], v: elems[2] }] 
    }); 
} 

DEMO

0

第一件事,我會存儲在變量placelist.lengthrawData.length循環之前,或在每次迭代它們將被重新計算:

var instlist = [{'place': 'a', 'data':[]}, {'place':'b', 'data':[]}]; 
var data = instlist; 

var placelistLen = placelist.length; 
var rawDataLen = rawData.length; 

for (var i = 0; i < placelistLen; i++){ 
for (var j = 0; j < rawDataLen; j++){ 
    if (rawData[j]['place'] == instlist[i]['place']) { 
     data[i]['data'].push({'t': rawData[j]['t'],'v': rawData[j]['v']}) 
     } 
    } 
} 

其次,如果你願意稍微改變輸出結構,你可以大大減少迭代次數。

var instlist = { 'a': [], 'b': [] }; 
var data = instlist; 
var rawDataLen = rawData.length; 

for (var i = 0; i < rawDataLen; i++) { 
    data[rawData[i]['place']].push({'t': rawData[i]['t'],'v': rawData[i]['v']}) 
} 

我不是專家,所以我不知道這會多快,但它確實刪除了條件並減少了迭代次數。另一方面,不同的數據結構可能不適合你的目的。