2017-07-11 9 views
4

私は階層構造に以下のようなノードが生じています:ネストされた配列の親レコードと子レコードを比較するには?

Node - 1 
    Node-1-1 
     Node-1-1-1 

は今、私は接続が親と子ノード間で定義するかどうかを確認したいです。親と子の間

接続ノード1とノード1-1間などについては、以下のように定義される:

"connections": { 
      "joins": [ 
      { 
       "parent": "Node-1", 
       "child": "Node-1-1" 
      } 
      ] 
     } 

が存在する場合には少なくとも1つの接続(1レコードが接続のプロパティを結合)親ノードと子ノードの間にある場合は、それ以外の場合はユーザーに警告を表示し、ノード間の接続が発生した直後に反復関数から戻したいと思う。

反復関数からの応答が得られない限り(反復関数は完了していない)、私は自分のIDをインクリメントしたくないので、コールバックを反復関数に渡して応答を返したいのです。

ノード1-1とノード1-1-1との間に接続がないので、接続の結合プロパティにレコードがないため、ユーザーに警告を表示したいと思います。

しかし、問題は、すべての親ノードと子ノードを比較する方法と、このコールバックを再帰的構造で管理する方法がわかりません。

var records = [ 
 
    { 
 
    "name": "Node-1", 
 
    "nodes": [ 
 
     { 
 
     "name": "Node-1-1", 
 
     "isParent": false, 
 
     "nodes": [ 
 
      { 
 
      "name": "Node-1-1-1", 
 
      "isParent": false, 
 
      "nodes": [ 
 
       
 
      ], 
 
      "connections": { 
 
       "joins": [] 
 
      } 
 
      } 
 
     ], 
 
     "connections": { 
 
      "joins": [ 
 
      { 
 
       "parent": "Node-1", 
 
       "child": "Node-1-1" 
 
      } 
 
      ] 
 
     } 
 
     } 
 
    ], 
 
    "isParent": true 
 
    } 
 
]; 
 

 

 
function CheckConnections(){ 
 
    var id=0; 
 
    iterate(records, 
 
       function (valid) { 
 
        if(valid) 
 
        { 
 
         id = id + 1; 
 
         console.log(id); 
 
        } 
 
        else 
 
         alert("please define connections") 
 
       } 
 
      ); 
 
     
 
} 
 

 
function iterate(nodes,callback) 
 
{ 
 
    var connectionDefine = false; 
 
    
 
    callback(false); 
 
}
<input type="button" value="Check Connections" onclick="CheckConnections()">

+0

、あなたは 'nodes'配列が親子接続の形で、' connections'配列にも存在していることを確認してすべてのオブジェクトを作るのチェックをしたいです? ノードに複数の子があった場合の構造はどのように見えますか? 'CheckConnections()'がtrue(エラーなし)を返す場合、構造体はどのように見えるでしょうか? – mTv

+0

@mTv:各親には子が1つしかなく、エラーがなければ単純にコールバックを返します(true)。それ以外の場合はコールバック(false) –

+0

空の 'joins'プロパティを持つノードがあるかどうか確認する必要がありますかまたは空ではないが何らかの形で無効にすることはできますか? – vassiliskrikonis

答えて

1

あなたがこれを行うには再帰関数を作ることができ、関数は2つのarguments--ノードとその親を取ります。各再帰で、使用可能な結合があり、結合の親が再帰中に渡された親と同じであるかどうかをチェックします。そして結合の子は現在のノード名でなければなりません。このような何か:あなたは、配列と親の名前でcheckを呼び出すための再帰的なアプローチを使用することができます

var records = [ 
 
    { 
 
    "name": "Node-1", 
 
    "nodes": [ 
 
     { 
 
     "name": "Node-1-1", 
 
     "isParent": false, 
 
     "nodes": [ 
 
      { 
 
      "name": "Node-1-1-1", 
 
      "isParent": false, 
 
      "nodes": [ 
 
       
 
      ], 
 
      "connections": { 
 
       "joins": [] 
 
      } 
 
      } 
 
     ], 
 
     "connections": { 
 
      "joins": [ 
 
      { 
 
       "parent": "Node-1", 
 
       "child": "Node-1-1" 
 
      } 
 
      ] 
 
     } 
 
     } 
 
    ], 
 
    "isParent": true 
 
    } 
 
]; 
 

 

 
function CheckConnections(){ 
 
    var id=0; 
 
    var inValidNodes = []; 
 
    records.forEach(function(node){ 
 
     inValidNodes = checkValidConnections(node, null); 
 
     if (inValidNodes.length > 0) 
 
      return; 
 
    }); 
 

 
    if(inValidNodes.length === 0) 
 
    { 
 
      id = id + 1; 
 
      console.log(id); 
 
     } else { 
 
     alert("please define connections " + inValidNodes); 
 
     } 
 
} 
 
function checkValidConnections(node, parent){ 
 
     var nodeName = node.name; 
 
     if(!node.isParent){ 
 
      var currentParentCondition = node.connections.joins.length > 0 && 
 
            node.connections.joins[0].parent === parent && 
 
            node.connections.joins[0].child === nodeName; 
 
      if (!currentParentCondition) 
 
       return [parent, nodeName]; 
 
     } 
 

 
     if (node.nodes.length > 0){ 
 
      return checkValidConnections(node.nodes[0], nodeName); 
 
     } else{ 
 
      return []; 
 
     }   
 
}
<input type="button" value="Check Connections" onclick="CheckConnections()">

+0

なぜノード[0]にハードコーディングされたインデックスnode.shouldntそれはノードですか? –

+0

@修正されたコードの学習。 – Dij

1

内部では、connections.joinsの最初のオブジェクトがテストされます。

結果はundefinedです。つまり、すべての接続が定義されているか、最初に接続がないオブジェクトが表示されます。

このチェックでは、呼び出し元オブジェクトの親の名前が使用されます。

(これにより、!o.isParent ...のようなチェックを省略することができ、最初の呼び出しparentにチェックを防ぐことになる、定義されていないので、parentのためだけのチェックは、代わりに使用することができる。)

function check(array, parent) { 
 
    var missing; 
 
    array.some(function (o) { 
 
     var j = o.connections && o.connections.joins && o.connections.joins[0]; 
 
     if (!o.isParent && (!j || j.parent !== parent || j.child !== o.name)) { 
 
      return missing = { parent: parent, child: o.name }; 
 
     } 
 
     if (o.nodes) { 
 
      return missing = check(o.nodes, o.name); 
 
     }     
 
    }); 
 
    return missing; 
 
} 
 

 
var records0 = [{ name: "Node-1", nodes: [{ name: "Node-1-1", isParent: false, nodes: [{ name: "Node-1-1-1", isParent: false, nodes: [], connections: { joins: [{ parent: "Node-1-1", child: "Node-1-1-1" }] } }], connections: { joins: [{ parent: "Node-1", child: "Node-1-1" }] } }], isParent: true }], 
 
    records1 = [{ name: "Node-1", nodes: [{ name: "Node-1-1", isParent: false, nodes: [{ name: "Node-1-1-1", isParent: false, nodes: [], connections: { joins: [ /* missing */ ] } }], connections: { joins: [{ parent: "Node-1", child: "Node-1-1" }] } }], isParent: true }]; 
 

 
console.log(check(records0)); // undefined, nothing missing 
 
console.log(check(records1)); // missing { parent: "Node-1-1", child: "Node-1-1-1" }

connections.joinsが単なるオブジェクトであり、指定された親/子が一致するかどうかを確認するための繰り返しが必要な配列ではない場合は、データ構造が少し改善されます。

+0

私の助けに向かってあなたの親切な努力のためにUpvotedしかし、私は配列として結合を取った理由は、親と子ノードの間に複数の接続が存在する可能性があります。 –

+0

@Learning、 問題を説明するために、いくつかのユースケースを質問に追加してください。 –

+0

mamは、この行でjoinの配列の中のすべてのレコードをチェックしていますか? :if(!o.isParent &&!o.connections.joins.some(function(p){return p.parent === parent && p.child === o.name;})) –

2

次の再帰的解決策は、最初に見つけられなかった接続関係のエラーを表示します。私は何が起こるかを追跡できるようにコメントを追加しました。

すべての接続を検査するわけではありません。子ノードと親ノードの間で適切に作成された接続が見つかると、高速で切断されて次のノードに移動します。

基本的には、現在の親子関係の接続が正しく記録されているかどうかを、各子ノードごとに検索することです。任意の数の子ノード/入れ子レベルで動作するはずです。

var records = [{"name":"Node-1","nodes":[{"name":"Node-1-1","isParent":false,"nodes":[{"name":"Node-1-1-1","isParent":false,"nodes":[],"connections":{"joins":[]}}], "connections":{"joins":[{"parent":"Node-1","child":"Node-1-1"}]}}],"isParent":true}]; 

function connections_control(records, parent = undefined) { 
    // Browse the nodes list 
    for (var node of records) { 
     // Control if the keys we need do exist 
     if (parent && node.connections && node.connections.joins) { 
      var found = false; 
      // Search in connections the current relation parent/child 
      for (var connection of node.connections.joins) { 
       if (connection.parent == parent && connection.child == node.name) { 
        found = true; 
        break; 
       } 
      } 
      if (!found) { 
       // We checked all connections, but we did not find our current relation! 
       console.log('Warning: Broken connection between parent node '+parent+' and child node '+node.name); 
       break; 
      } 
     } 
     if (node.nodes) { 
      // The current node becomes parent, start again with the inner nodes list 
      connections_control(node.nodes, node.name); 
     } 
    } 
} 

connections_control(records); 

文書をルートから取得している最初のループでは、親は存在しないため、接続の検索は行われません。

実行:だから、

nodejs childs.js 
Warning: Broken connection between parent node Node-1-1 and child node Node-1-1-1 
関連する問題