2010-04-20 67 views
2

给定两个不同类型的IEnumberables,迭代两个列表以执行所有可能组合的操作的最佳实践(考虑可读性和可维护性)是什么?枚举不同类型的列表的所有组合

我最初的解决方案是使用嵌套的foreach循环,遍历第一个IEnumerable,然后在该循​​环内迭代第二个IEnumerable,并将外部和当前循环的值传递给目标方法。例如:

enum ParamOne 
{ 
    First, 
    Second, 
    Etc 
} 

List<int> paramTwo = new List<int>() { 1, 2, 3 }; 

void LoopExample() 
{ 
    foreach (ParamOne alpha in Enum.GetValues(typeof(ParamOne))) 
    { 
     foreach (int beta in paramTwo) 
     { 
      DoSomething(alpha, beta); 
     } 
    } 
} 

我试图用LINQ重构它,但结束了没有明显的优势,似乎不那么直观的东西。这里的搜索显示了很多关于嵌套foreach的问题以迭代子属性,但我找不到关于遍历两个不同列表的任何内容。

回答

1

我没有看到你的解决方案有什么特别不对。话虽这么说,最简单的LINQ程序似乎是:

foreach(var entry in enumerable1.SelectMany(
      e => enumerable2.Select(e2 => new { First = e, Second = e2 }))) 
{ 
    DoSomething(entry.First, entry.Second); 
} 

鉴于这是一个有点... ...钝我会建议用两个foreach操作坚持。这比C#编译器为了使表达式正常工作而要经历的所有恶意代码都要便宜(因为我们正在处理闭包和匿名类型)。

+0

这证实了我的结论 - 我提出的LINQ过程基本上和你的一样,我同意它看起来比嵌套'foreach'循环更加钝。 – jball 2010-04-20 22:47:55

+0

另一方面,如果你需要过滤掉一些东西,并可以得到LINQ,它可能是一个胜利。 – BCS 2010-05-18 14:47:42

+0

@BCS:很明显,我不能与这种说法争辩,但我认为最好与问题中提出的方案一致。否则,我们可以想出适合各种解决方案的假设情况是没有限制的。换句话说,我宁愿拿出一个解决方案来适应这种情况,而不是一个适合解决方案的场景;) – 2010-05-18 14:58:36

1

只要组合中没有重叠,我就没有看到在两组笛卡尔乘积上计算函数的计算效率更高的方法。但是,如果两个列表中的任何一个具有重复的元素,或者DoSomething的参数顺序无关紧要,并且列表中存在重叠,则会产生冗余调用DoSomething。您可以通过记住DoSomething节省计算时间。