Удаление повторяющихся ребер из массива для графа, ориентированного на d3 force

#javascript #node.js #d3.js

#javascript #node.js #d3.js

Вопрос:

У меня есть массив ребер для графа, ориентированного на силу, который выглядит примерно так, но намного длиннее.

    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 amp;amp; 
                     rawLinks[i].target != rawLinks[j].source){

         links.push(rawLinks[i])
        }
      }
  }   
  

Я почти уверен, что проблема в моем операторе if. Или это совершенно неправильный подход?

Как обычно, я уверен, что это очевидно для кого-то со свежим взглядом. Что не так с моим кодом?

Ответ №1:

Поскольку не имеет значения, кто является источником, а кто целью («от 1 до 2» совпадает с «от 2 до 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 
           amp;amp; 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 amp;amp; myArray[i-1].target === myArray[i].target){
            myArray.splice(i, 1);
            } else {
            i  ;
            }
        }
    return myArray;
    }  

removeDups(rawLinks);

console.log(rawLinks);