繁体   English   中英

如何检查节点是否相关? 如果有两个邻居,我该如何选择呢?

[英]How to check if nodes are related? How do I chose only one neighbour if it has two?

我在D3中有一个部队布局。

我有很多带有链接的节点。 我的问题是,如果节点满足特定条件,我想删除链接。

假设我有节点A,B,C。

说这个tilda字符-“〜”表示已连接。

If (A~B && A~C && B~C){

DELETE THE A~C link. //which would leave A~B~C
}

我试图通过每个链接:

link.forEach(function{d){ ....

但我似乎无法理解如何执行逻辑。

我将遍历每个节点3次,检查A〜B,A〜C,B〜C,但是如果我有100个节点,那将会非常慢。

任何帮助,将不胜感激 :)

这是我当前的edges / links数组的外观:

edges = [
{
    "source": "A",
    "target": "B",
    "other information" : "randomstring",
    "other information" : "randomstring"
},
{
    "source": "B",
    "target": "C",
    "other information" : "randomstring",
    "other information" : "randomstring"
} // and so on ....
]

这是一个图论问题,我假设您想打破一个循环,这就是我要做的

给定大小为n且阶为m的图g

1)从links构建一个哈希表,该哈希表将两个带有链接的节点映射O(m)如果哈希是在恒定时间内完成的,则为O(m) ),例如

// a reference to the link itself (which can be an object or a dom node)
var hash = {}
links.each(function (d) {
  var u = d.source
  var v = d.target
  hash[u] = hash[u] || {}
  // again replace this with the dom node if you want
  hash[u][v] = d
})

2)运行dfs查找后边缘(在我写的文章中或通过谷歌快速搜索找到更多关于后边缘的信息),每当找到后边缘时,您将获得有关源/目标节点和周期长度O(n + m)

3)如果周期的长度是3或您的标准是什么,则删除链接,从链接中擦除将花费O(km) ,其中k是找到的周期数

现在使用d3,您可以简单地重新绑定新数据(删除一些链接)并重新呈现图形

假设你的逻辑可以简化为检查当前entry.source等于以下entry.target,你可以使用array.reduce

    edges = [
    {
        "source": "A",
        "target": "B",
        "other information" : "randomstring",
        "other information" : "randomstring"
    },{
        "source": "A",
        "target": "C",
        "other information" : "randomstring",
        "other information" : "randomstring"
    },{
        "source": "B",
        "target": "C",
        "other information" : "randomstring",
        "other information" : "randomstring"
    },{
        "source": "D",
        "target": "C",
        "other information" : "randomstring",
        "other information" : "randomstring"
    },{
        "source": "C",
        "target": "E",
        "other information" : "randomstring",
        "other information" : "randomstring"
    }
]




var res = edges.reduce(function (acc, cur, i, array) {

    if (array[i - 1] == undefined || acc[acc.length - 1].target == cur.source) {
        acc.push(cur)
    }

    return acc

}, [])
console.log(res)

小提琴

这可能不是最有效的解决方案,但是检查100个对象应该没问题; 此外,它是完全合成的,并且还很好地使用了reduce

似乎我们遇到了类似的问题,即我必须创建一个函数才能到达特定节点。 您可以在创建和使用的地方看到相同基本功能的不同版本: http : //bl.ocks.org/CrandellWS/79be3b8c9e8b74549af5

最初的尝试是使用forEach循环,但我发现使用常规的for循环更简单。 尽管我希望这可以解决您的问题,但是您应该阅读以下答案 :为什么在数组迭代中使用“ for…in”是一个坏主意?

  function getObjByValue(myRoot, myType, myType2, myVal, myVal2){
    var d;
    console.log(typeof myRoot)
    if(typeof myRoot == "object"){
      for(d in myRoot){

        //checking for requirements.
        if(myRoot[d][myType] == myVal && myRoot[d][myType2] == myVal2 ){
          console.log(d);

          //accessing the specific one desired...
          d3.select('#specificOne').text(myRoot[d]["other information"]);

          //deleteing it from the copied array
          delete myRoot[d];

          //do something with the rest
          printRemaining(myRoot);

            //done
            return;
        }
      }
    }
  } 

getObjByValue(edges, 'source', 'target', 'A', 'C');

 edges = [ { "source": "A", "target": "B", "other information" : "randomstringAB", "other information2" : "randomstringAB" },{ "source": "A", "target": "C", "other information" : "randomstringAC", "other information2" : "randomstringAC" },{ "source": "B", "target": "C", "other information" : "randomstringBC", "other information2" : "randomstringBC" },{ "source": "D", "target": "C", "other information" : "randomstringDC", "other information2" : "randomstringDC" },{ "source": "C", "target": "E", "other information2" : "randomstringCE", "other information" : "randomstringCE" } ] function getObjByValue(myRoot, myType, myType2, myVal, myVal2){ var d; console.log(typeof myRoot) if(typeof myRoot == "object"){ for(d in myRoot){ if(myRoot[d][myType] == myVal && myRoot[d][myType2] == myVal2 ){ console.log(d); //accessing the specific one desired... d3.select('#specificOne').text(myRoot[d]["other information"]); //deleteing it from the copied array delete myRoot[d]; printRemaining(myRoot); console.log(d); console.log('done'); //done return; } } } } function printRemaining(myArray){ for(d in myArray){ d3.select('#edges').append('p').text(myArray[d]["other information"]+'\\r\\n'); } } getObjByValue(edges, 'source', 'target', 'A', 'C'); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <p>First the specific one</p> <div id="specificOne"></div> <br /><br /><br /><br /><br /> <p>It's time to eat, Here is the leftovers.</p> <div id="edges"></div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM