2015-10-16 37 views
0

我有一個看起來像這樣的網絡數據的CSV文件:爲什麼我的map函數不能返回d3 js中的所有csv文件行?

node,edges,centrality_degree 
1,"[(1, 2), (1, 3), (1, 4), (1, 5)]",1.0 
2,"[(2, 1), (2, 3), (2, 4), (2, 5)]",1.0 
3,"[(3, 1), (3, 2), (3, 4), (3, 5)]",1.0 
4,"[(4, 1), (4, 2), (4, 3), (4, 5)]",1.0 
5,"[(5, 1), (5, 2), (5, 3), (5, 4)]",1.0 

的目標是產生一個網絡中的所有數據。我已經在繪製節點了。但是,我遇到了試圖映射邊緣的問題。下面的代碼只是正確地返回了五個第一個節點對,但它在那裏停止。

var list = []; 

    d3.csv("/graphs/documents/1/2015/10/15/16_43_12_data.csv", function(error, d) { 

    // var links_list = [ {"source": 1, "target": 0},{"source": 2, "target": 0},{"source": 3, "target": 0}, {"source": 4, "target": 0}]; 

    // var nodes = [ {"name": 1}, {"name":2}, {"name":3}, {"name":4}, {"name":5}]; 

    var nodes = d.map(function(d){ return {"name":+d.node}; }); 

    var links_list = d.map(function(d) { 

     list_array = JSON.parse(d.edges.replace(/\(/g,"[").replace(/\)/g,"]")); 
     console.log(list_array); 

     var i, len = list_array.length; 

     for (i=0; i<len; i++) {        
      var s = arrayObjectIndexOf(nodes, list_array[i][0], "name"); 
      var t = arrayObjectIndexOf(nodes, list_array[i][1], "name"); 

      list.push({source: s ,target: t }); 
      return {source: s , target: t }; 
     } 
    }); 

... #create the graph using the data 

}); 

了var links_list返回5名對象,其中所述一對源,目標的陣列對應於所述的值: (1,2),(1,3),(1,4) ,(1,5),(2,1)

當我在console.log(list_array)上打印時,它返回具有4個元素的數組5次。 links_list爲什麼不計算這些值? 列表數組也返回相同的東西......發生了什麼?這是一個邏輯問題嗎?我感謝您的幫助。

+0

list_array是一個包含五個元素的數組。所以當你把我放到len上的時候,你會推到列表五次。 – ee2Dev

回答

1

這裏有很多問題,其中第一個問題是你在for循環中從你的map函數返回,所以你的for循環實際上並沒有做任何事情。

第二個可能的問題(不知道)是我見過的D3圖形應用程序存儲節點的實際JS引用的邊緣,而不是隻是一個指標,所以{source:nodes[s], target:nodes[t]}

我會做一個幾個變化,使其更易於理解和更容易理解:

首先,沒有什麼特別的關於邊緣列出哪些行(除了人類可讀性的文件格式),所以爲了更容易推理程序,我只是把它們全部堆成一大堆而不是試圖嵌套循環:

function flatten(a,b){return a.concat(b);} 
var edgeNumbers=d.map(function(row){ 
    return JSON.parse(row.edges.replace(/\(/g,"[").replace(/\)/g,"]")) 
}).reduce(flatten,[]); 

其次,(假設我正要存儲refereces中的邊緣,而不是indexe號碼正確)通過使用對象,我將「索引」您的節點數組:

function indexBy(key){return function(prev,x){prev[x[key]]=x;return prev;};} 
var nodesByName=nodes.reduce(indexBy("name"),{}); 

從那裏,邊緣是簡單地說:

edgeNumbers.map(function(namepair){ 
    return {source:nodesByName[namepair[0]],target:nodesByName[namepair[1]]}; 
}); 
+0

你救了我的命。不過,我現在覺得很愚蠢......我認爲map會迭代通過數據,比如csv函數,讀取行......是的,你是正確的節點引用,而不是id,所以這就是爲什麼我使用arrayObjectIndexOf。 ..我在哪裏可以找到更多信息成爲更好的程序員?我已經編寫了幾年的代碼,但有時候我會一直陷入這些讓我覺得自己一無所知的小錯誤。謝謝! –

+1

地圖遍歷數據。但是您使用它來迭代行,您需要另一種方法來迭代這些行中的邊。你的'for'循環會爲此工作,除非你通過返回來破壞它。我不知道它是否會對你有所幫助,但對我來說,學習函數式編程有助於避免大量由脆性循環和狀態變異引起的邏輯錯誤 –

相關問題