我正在尝试构造一个linq查询,该查询将规则应用于来自两个输入集A和B的域中的布尔函数列表。
但是,我想在找到匹配时“中断”,所以我最终得到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-&gt; 1。似乎这将允许我按顺序应用主要规则和回退规则,但不会产生额外的映射。
答案 0 :(得分:3)
听起来你正在寻找enumerable.TakeWhile(predicate)
来自MSDN的示例:
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
*/
答案 1 :(得分: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