2011-11-08 35 views
0

我試圖構造一個linq查詢,該規則將規則應用於來自兩個輸入集A和B的域的布爾函數列表。是否有可能「斷開」LINQ到對象查詢?

但是,我想在發現匹配時「休息」所以我最多隻能得到A的每個元素的一個結果。

我希望這對於那些經驗豐富的功能性人員來說是有意義的 - 我的感覺是我在跟蹤事物的方式是一致的那個世界,但我不知道我是否真的在正確的軌道上...

這是代碼,希望這很清楚我在做什麼:

List<int> a = new List<int>(); 
a.Add(1); 
a.Add(2); 
List<int> b = new List<int>(); 
b.Add(1); 
b.Add(2); 
Func<int, int, string> map = (i, j) => i + "->" + j; 
var rules = new List<Func<int,int,Tuple<bool, Func<int, int, string>>>>(); 
rules.Add((i, j) => new Tuple<bool, Func<int,int,string>>(i == j, (ii, jj) => map(ii, jj)));         
rules.Add((i, j) => new Tuple<bool, Func<int,int,string>>(i+j == 2, (ii,jj) => map(ii,jj)));        
var q = from ai in a 
     from bi in b 
     from rule in rules 
     let tuple = rule(ai, bi) 
     where tuple.Item1 == true 
     select tuple.Item2(ai, bi); 

導致:

1->1 

1->1 

2->2 

期望的結果:

1->1 

2->2 

我倒是喜歡有發生的情況是,當第一規則匹配1-> 1,我可以排除第二個1-> 1。看起來,這將允許我有主要規則和後備規則按順序應用,但不會產生額外的映射。

回答

3

這聽起來像你從MSDN尋找enumerable.TakeWhile(predicate)

例子:

 string[] fruits = { "apple", "banana", "mango", "orange", 
           "passionfruit", "grape" }; 

     IEnumerable<string> query = 
      fruits.TakeWhile(fruit => String.Compare("orange", fruit, true) != 0); 

     foreach (string fruit in query) 
     { 
      Console.WriteLine(fruit); 
     } 

     /* 
     This code produces the following output: 

     apple 
     banana 
     mango 
     */ 
+0

謝謝很酷。出於某種原因,我從來不知道TakeWhile。 – aevanko

1

這是明顯的用武之地。由於每個規則都是通過其規則表示確定,你可以簡單地對輸出信號進行不同的,意思是:

 var q = from ai in a 
       from bi in b 
       from rule in rules 
       let tuple = rule(ai, bi) 
       where tuple.Item1 == true 
       select tuple.Item2(ai, bi); 

     q = q.Distinct().ToArray(); 

將導致:

1->1 

2->2 

而不是

1->1 

1->1 

2->2