我(或可能是其他任何人)拥有一个我需要迭代的对象列表然后与属性列表进行交互并不少见。我使用嵌套循环,如下所示:
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路径。这只是我正在寻找的那种快乐的代码!
答案 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语句替换你的循环。当然,您可能仍需要迭代结果集。
答案 7 :(得分:0)
我喜欢Ayende的pipes and filters,但它比简单循环的内置LINQ代码要多得多(我假设问题中的代码示例很简单)。