2011-11-08 95 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