2016-03-29 8 views
0

に私は次の形式で木構造データを持っています:問題は、C#

H1  
    H1 - 1 
     H1 - 1 - 1 
      H1 - 1 - 1 - 1 
       H1 - 1 - 1 - 1 -1 
        H1 - 1 - 1 - 1 -1 - 1 
     H1 - 1 - 2 
     H1 - 1 - 3 
    H1 - 2 
     H1 - 2 - 1 
     H1 - 2 - 2 

H2  
H3  
    H3 - 1 
     H3 - 1 - 1 
      H3 - 1 - 1 - 1 
       H3 - 1 - 1 - 1 - 1 
      H3 - 1 - 1 - 2 
     H3 - 1 - 2 
     H3 - 1 - 3 
    H3 - 2 

私は、アイテムが子アイテムのIDを渡すことによって、上記ツリーのどこに存在するかどうかを確認する必要があります私は上記のツリーのすべての項目をトラバースする必要があります。私はこれまでのところ、以下の再帰的な方法を書かれている:

public bool CheckIfChildItemExists(Item parentItem, long childItemId) 
{ 
    var isChildExisting = false; 
    foreach (Item item in parentItem.Children) 
    { 
     if (item == context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault() || item.Children.Contains(context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault())) 
     { 
      isChildExisting = true; 
      return isChildExisting; 
     } 
     else 
     { 
      return CheckIfChildItemExists(item, childItemId); 
     } 
    } 
    return isChildExisting; 
} 

上記の方法を使用して:

  • ルート項目H1, H2, H3がアクセス可能です。
  • H1H1 -1H1 - 1 - 1H1 - 1 - 1 -1など)のすべての支店にアクセスできます。
  • H1 - 2 - 1およびH1 - 2 - 2はアクセス不可能で、通過していません。彼らの親アイテムH1 - 2にはアクセスできます。
  • H3のすべての子はアクセスできません。

私の方法では何が間違っていますか?

+0

List がroot/parentではないようですが、このケースを処理する必要があります。 –

+0

@HariPrasad私は質問に記載されている子データを持つメソッドに渡している 'parentItem'の子にアイテムが存在するかどうかをチェックする必要があります。 'H1、H2、H3'は子項目です。 – seadrag0n

答えて

2

早く帰ってきました。あなたがしていることは、実際にルートからリーフまで多くても1つのブランチでチェックインしますが、他のブランチをチェックすることはありません。

public bool CheckIfChildItemExists(Item parentItem, long childItemId) 
{ 
    foreach (Item item in parentItem.Children) 
    { 
     if (item == context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault() || item.Children.Contains(context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault())) 
     { 
      return true; 
     } 
     else 
     { 
      var childItemExists = CheckIfChildItemExists(item, childItemId); 
      if(childItemExists) return true; // else continue search in other children 
     } 
    } 
    return isChildExisting; 
} 

しかし私は、あなたがif文で右の条件をしていることを確認していません。すべてのアイテムが検索対象となる場合は、コードを試してみてください。すべてのルート項目に対してこの手順を実行するか、関数に渡す人工ルート項目が必要です。あなたが実際に2つのオブジェクトを比較しているitem == context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault()

public bool CheckIfChildItemExists(Item parentItem, long childItemId) 
{ 
    if(parentItem.ItemID == childItemId && parentItem.IsActive) return true; 
    foreach (Item item in parentItem.Children) 
    { 
     var childItemExists = CheckIfChildItemExists(item, childItemId); 
     if(childItemExists) return true; // else continue search in 
    } 
    return false; 
} 

、なぜだけでなくitemオブジェクトに対して条件をご確認ください!あなたは代わりにcontext.Items.FirstOrDefault(x => x.ItemID == childItemId && x.IsActive)を使用することができます。

+0

私は 'item == context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault()'ループの現在の 'Item'が' ChidItem'であるかどうかをチェックする条件を追加しました。私たちが探しているのは、この条件を削除すると、ルートレベルの親H1、H2、H3がスキップされ、検索されたChildItemがH1、H2またはH3である場合、その子だけが通過することになります。 – seadrag0n

+0

現在のノードの子/孫が条件を満たしているかどうかのチェックを取り除くようにしてください。各ノードごとに別々に実行するのが再帰の仕事です。 –