从d3有向图的数组中移除重复的边

Removing duplicate edges from an array for a d3 force directed graph

本文关键字:d3 有向图 数组      更新时间:2023-09-26

我有一个力有向图的边数组,它看起来像这样,但更长。

   var rawLinks = [{ source: 1, target: 2 },
                  { source: 2, target: 1 },
                  { source: 6, target: 7 },
                  { source: 7, target: 6 },
                  { source: 8, target: 9 },
                  { source: 8, target: 9 },
                  { source: 8, target: 86 },
                  { source: 8, target: 101 },
                  { source: 8, target: 133 },
                  { source: 8, target: 134 }]

由于这些是曲面上的点,因此我想删除会导致点之间重复线的元素。

例如,我只需要前两个元素中的一个,因为它们会导致从1到2的行,以及从2到1的行。我只需要1和2之间的一条线。

我已经试过了,但是我得到了意想不到的结果。

var links = [];
for (var i=0; i<rawLinks.length; i++) {
      for (var j=0; j<rawLinks.length; j++) {
        if(rawLinks[i].source != rawLinks[j].target && 
                     rawLinks[i].target != rawLinks[j].source){
         links.push(rawLinks[i])
        }
      }
  }   

我很确定我的if语句是问题所在。或者这是完全错误的方法?

像往常一样,我相信这对新手来说是显而易见的。我的代码有什么问题?

既然谁是源谁是目标并不重要("1 to 2"与你的问题中的"2 to 1"相同),我们将首先重新组织数组:

rawLinks.forEach(function(d){
    var sourceTemp = d.source, targetTemp = d.target;
    if(d.source > d.target){
        d.source = targetTemp;
        d.target = sourceTemp;
    }
});

创建副本,像这样:

{ source: 1, target: 2 }
{ source: 1, target: 2 }    

然后,删除重复项:

function removeDups(myArray){
    myArray.sort();
    for(var i = 1; i < myArray.length; ){
        if(myArray[i-1].source === myArray[i].source 
           && myArray[i-1].target === myArray[i].target){
            myArray.splice(i, 1);
        } else {
            i++;
        }
    }
    return myArray;
}

下面是一个示例:

var rawLinks = [{ source: 1, target: 2 },
    { source: 2, target: 1 },
    { source: 6, target: 7 },
    { source: 7, target: 6 },
    { source: 8, target: 9 },
    { source: 8, target: 9 },
    { source: 8, target: 86 },
    { source: 8, target: 101 },
    { source: 8, target: 133 },
    { source: 8, target: 134 }];
									
rawLinks.forEach(function(d){
	var sourceTemp = d.source; targetTemp = d.target;
	if(d.source > d.target){
		d.source = targetTemp;
		d.target = sourceTemp;
	}
});
function removeDups(myArray){
    myArray.sort();
    for(var i = 1; i < myArray.length; ){
        if(myArray[i-1].source === myArray[i].source && myArray[i-1].target === myArray[i].target){
            myArray.splice(i, 1);
            } else {
            i++;
            }
        }
    return myArray;
    }  
removeDups(rawLinks);
console.log(rawLinks);