2011-12-21 1 views
8

再帰を行って、子を持つことができる複数の子があるリスト内の長い値を見つけます。方法以下の何かを返すときに再帰を完全に停止する

:私はreturn td;を行う際

public TaxonomyData getTaxonomyData(long taxId, List<TaxonomyData> TaxonomyTree, TaxonomyData output) 
{ 
    //find taxid in the taxonomy tree list and return the taxonomydata 

    foreach (TaxonomyData td in TaxonomyTree) 
    { 
     if (td.TaxonomyId == taxId) 
     { 
       output = td; 
       //return td; => when doing a return here means I already found a match so it is not necessary to do all the recursion. 
     } 
     else if (td.Taxonomy.Length > 0) 
     { 
      getTaxonomyData(taxId, td.Taxonomy.ToList(), output); 
     } 
    } 

    return output; 
} 

は、それは私の全体の再帰が停止していること(コメント行を参照)は可能ですか?

public TaxonomyData GetTaxonomyData(long taxId, IEnumerable<TaxonomyData> tree) 
{ 
    foreach (TaxonomyData td in tree) 
    { 
     if (td.TaxonomyId == taxId) 
     { 
      return td; 
     } 
     else 
     { 
      // See if it's in the subtree of td 
      TaxonomyData data = GetTaxonomyData(taxId, td.Taxonomy); 
      if (data != null) 
      { 
       return data; 
      } 
     } 
    } 
    // Haven't found it anywhere in this tree 
    return null; 
} 

returnが一つだけのレベルを返しますが、else句で戻り値をチェックすることによって、我々はスタックまでのすべての方法を返すことができます:私はあなたのような何かをしたい疑い

おかげ

+0

は、それが起こるのだろう、心配しないでください。再帰はそこで止まるでしょう。 –

+0

getTaxonomyDataの再帰呼び出しを停止することをお考えですか?あなたが既に必要とする価値を持っているためにforeachで無計画にループするのを避けようとするなら、あなたがしなければならないことは "break"を加えることです。 "出力= td;の直後命令。そして、私はこのケースではしばらくの間、より良い解決策になると思っています... –

+0

@Jani:再帰は 'else'節からのものなので、再帰*戻り値を返し、 'TaxonomyTree'の次の要素をそのまま使い続けます。 –

答えて

14

正しい値を見つけたら

呼び出し元に返される最終結果は、見つからない場合はnull参照になります。

refパラメータではなかったので、出力パラメータを削除しましたが、戻り値を使用してのようにはっきりしません。

+0

これは、1つのコールを保存するだけです。それは不必要なIMHOです。 –

+0

私は末尾の再帰が解決策だと思っています –

+0

@Jani:あなたは何を意味するのか分かりません。元のコードは単純に機能しません。再帰呼び出しの結果をまったく使用していません。 –

1

私はおそらく遅く、思い付いたが、そこに行くLINQの拡張ソリューション..

public static class Ext 
{ 
    public static T SingleOrDefault<T>(this IEnumerable<T> enumerable,Func<T,bool> predicate, Func<T,T> defaultSelector) 
     where T : class 
    { 
     return enumerable.SingleOrDefault(predicate) ?? enumerable.SkipWhile<T>(t=>defaultSelector(t) == null).Select(defaultSelector).SingleOrDefault(); 
    } 

    public static TaxonomyData Get(this IEnumerable<TaxonomyData> tree, int taxId) 
    { 
     return tree.SingleOrDefault(t=> t.TaxonomyId == taxId,t=>t.Taxonomy.Get(taxId)); 
    } 
}