调用同伴代码书呆子 - 嵌套循环的替代方案?

时间:2008-12-13 15:50:11

标签: c# linq loops

我(或可能是其他任何人)拥有一个我需要迭代的对象列表然后与属性列表进行交互并不少见。我使用嵌套循环,如下所示:

IList<T> listOfObjects;
IList<TProperty> listOfProperties;

foreach (T dataObject in listOfObjects)
{
    foreach (TProperty property in listOfProperties)
    {
        //do something clever and extremely useful here
    }
}

这是针对此问题的时间和性能测试模式吗?或者有更高性能,更优雅,或者只是简单有趣(当然仍然可读和可维护)?

上面的代码并没有让我微笑。有人可以帮助我的循环带来一些快乐吗?

谢谢!

更新:我在最正面的意义上使用术语“书呆子”。作为维基百科定义的一部分,它将“指的是一个热衷于追求智力活动的人”。 “代码书呆子”我指的是一个关心不断改进自己作为程序员,寻找新的,新颖的,优雅的快速,可维护和美丽的编码方式的人!他们很高兴退出VB6并希望聪明的人批评他们的代码并帮助他们自己聪明。 (注意:他们也喜欢制作以-ify结尾的新单词。)

最后的说明:

感谢Dave R,Earwicker和TheSoftwareJedi将我送回Linq路径。这只是我正在寻找的那种快乐的代码!

8 个答案:

答案 0 :(得分:8)

嵌套循环当然没有问题。它们快速,可读,并且自软件开发迈出第一步以来一直存在。

当您想要在迭代集合时执行操作时,您可能会发现LINQ将是一个有趣的探索途径:

http://msdn.microsoft.com/en-us/vcsharp/aa904594.aspx

你将自己限制在更高版本的框架(3.5以后),但实际上你可能会发现功能编程方法相当优雅。沿着这条路走下去的其他语言功能包括lambdas和匿名方法,这些方法本身就很吸引人。

祝你好运,我希望你在途中获得乐趣 - 这是一个很好的方法:)

答案 1 :(得分:8)

看起来您正在尝试将笛卡尔加入两个列表,并应用where子句。这是一个简单的示例,显示了执行此操作的Linq语法,我认为这是您正在寻找的。 list1和list2可以是任何IEnumerable,你的where子句可以包含更详细的逻辑,在你的select子句中你可以抽出你需要的东西。

        var list1 = Enumerable.Range(1, 100);
        var list2 = Enumerable.Range(1, 100);

        foreach (var item in from a in list1
                             from b in list2
                             where a % b == 0
                             select new { a, b })
        {
            Console.WriteLine(item);
        };

性能与您发布的内容相同 - 不希望在这方面误导。我更喜欢这种Linq语法。

答案 2 :(得分:5)

foreach (var pair in from obj in listOfObjects
                     from prop in listOfProperties  
                     select new {obj, prop})
{
   Console.WriteLine(pair.obj + ", " + pair.prop);
}

答案 3 :(得分:3)

如果你需要对每个对象和每个属性做一些事情,那么就没有太多工作要做。你可能能够做一些语法上令人愉快的事情,但是没有办法完成这项工作。

如果您只处理对象和/或属性的子集,请对其进行过滤(使用linq到对象,如果您正在执行.net 3.5)!

您可能会喜欢Filter/Map/Reduce用于集合,以便为执行集合操作引入更好的语法。

答案 4 :(得分:2)

Action<T, TProp> somethingClever = //your clever method

listOfObjects
  .SelectMany(
    o => listOfProperties,
    (o, p) => new {o, p})
  .ToList()
  .ForEach(x => somethingClever(x.o, x.p));

答案 5 :(得分:2)

虽然我确实喜欢Linq解决方案的优雅,但我认为我的建议是将内循环提取到方法中;您的代码最终会看起来像:

foreach(dataObject in listOfObjects)
    DoSomethingCleverWithProperties(dataObject, listOfProperties);

这对我来说更难以维持。

答案 6 :(得分:0)

在这种情况下,我们通常会过滤我们感兴趣的部分。 你的块dosomethingclever()通常以

开头
foreach (T dataObject in listOfObjects)
{    
  foreach (TProperty property in listOfProperties)    
  {
    if (property.something == "blah") 
    { // OK, we found the piece we're interested in...

      // do something clever...

    }
  }
}

这是LINQ是你的朋友,允许你用select语句替换你的循环。当然,您可能仍需要迭代结果集。

Tons of samples here

答案 7 :(得分:0)

我喜欢Ayende的pipes and filters,但它比简单循环的内置LINQ代码要多得多(我假设问题中的代码示例很简单)。