2015-10-16 40 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'循环会为此工作,除非你通过返回来破坏它。我不知道它是否会对你有所帮助,但对我来说,学习函数式编程有助于避免大量由脆性循环和状态变异引起的逻辑错误 –

相关问题