2011-12-21 19 views
8

Tôi làm đệ quy để tìm một giá trị dài trong Danh sách có nhiều trẻ em cũng có thể có con.Dừng đệ quy hoàn toàn khi trả lại một cái gì đó

phương pháp sau đây:

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; 
} 

Có thể khi tôi làm return td; (xem hàng nhận xét) mà toàn bộ đệ quy của tôi dừng lại?

Cảm ơn

+0

Đừng lo lắng, nó sẽ xảy ra. Việc đệ quy sẽ dừng lại ở đó. –

+0

Bạn có chắc chắn đang nói về việc dừng các cuộc gọi đệ quy tới getTaxonomyData không? Nếu bạn đang cố gắng tránh lặp đi lặp lại một cách vô tình với việc rao giảng vì bạn đã có giá trị bạn cần thì những gì bạn phải làm là thêm "break"; ngay sau "output = td;" chỉ dẫn. Và tôi nghĩ trong trường hợp này một thời gian sẽ là giải pháp tốt hơn ... –

+0

@Jani: Không, đệ quy * sẽ không * dừng nếu cuộc gọi sâu chỉ trả về - vì đệ quy sẽ từ mệnh đề 'else', bỏ qua giá trị trả về và chỉ tiếp tục với phần tử tiếp theo của 'TaxonomyTree'. –

Trả lời

14

tôi nghi ngờ bạn muốn một cái gì đó như:

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; 
} 

Mỗi return chỉ trả một mức độ, nhưng bằng cách kiểm tra giá trị trả về trong mệnh đề else, chúng ta có thể trả lại tất cả các con đường lên ngăn xếp khi chúng tôi tìm thấy giá trị phù hợp.

Kết quả cuối cùng được trả lại cho người gọi sẽ là tham chiếu không có giá trị nếu nó không được tìm thấy.

Lưu ý rằng tôi đã xóa thông số "đầu ra", mặc dù không phải là thông số ref và không rõ ràng là chỉ sử dụng giá trị trả về.

+0

Điều đó chỉ lưu một cuộc gọi. và IMHO không cần thiết. –

+0

Tôi nghĩ rằng đệ quy đuôi là giải pháp –

+0

@Jani: Tôi không chắc chắn những gì bạn có ý nghĩa. Mã ban đầu chỉ đơn giản là không hoạt động - nó không sử dụng kết quả của cuộc gọi đệ quy. –

1

Một giải pháp mở rộng LINQ tôi đã đưa ra, có thể chậm nhưng có bạn đi ..

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)); 
    } 
} 
Các vấn đề liên quan