我有一个嵌套foreach
集合的方法(迭代一组对象,然后查看每个对象)。我在一本书中看到了一个很好的模式,使这个更优雅,但不记得/找到代码示例。我怎么能让它更整洁?
代码只是一个典型的嵌套foreach
语句,所以我没有提供代码示例。
答案 0 :(得分:11)
你必须更加具体地说明你对“更优雅”的意思,因为对于嵌套的foreach
,IMO没有什么特别的不优雅的。
话虽如此,.NET 3.5及更高版本中的LINQ扩展方法可以提供帮助(特别是SelectMany
)。
public class Foo
{
public List<string> Strings { get; set; }
}
...
List<Foo> foos = new List<Foo>();
foreach(string str in foos.SelectMany(f => f.Strings))
{
...
}
答案 1 :(得分:7)
显而易见的解决方案是压缩方法。
旧:
void SubmitOrders()
{
var orders = GetOrders();
foreach (Order o in orders)
{
foreach (OrderDetail d in o.Details)
{
// Blah...
}
}
}
新:
void SubmitOrders()
{
var orders = GetOrders()
foreach (Order o in orders)
{
SubmitOrder(o);
}
}
void SubmitOrder(Order order)
{
foreach (OrderDetail d in order.Details)
{
// Blah...
}
}
这里的其他答案似乎都集中在Linq上,我同意如果你的循环没有副作用(即你只是想从最里面的循环中提取一些信息),那么您可以使用一个或两个简单的Linq语句重写整个事物。如果涉及副作用,那么只需遵循经过时间考验的子程序实践。
答案 2 :(得分:5)
在:
foreach(Customer c in Customers)
{
foreach(Order o in c.Orders)
{
o.Dance();
}
}
后:
foreach(Order o in Customers.SelectMany(c => c.Orders))
{
o.Dance();
}
答案 3 :(得分:1)
您可以使用LINQ SelectMany运算符:
foreach (var bar in model.FooCollection.SelectMany(f => f.Bars))
{
// Do Stuff
}
答案 4 :(得分:1)
很难在没有任何上下文或代码段的情况下给出答案。但是,Martin Fowler有一篇关于重构LINQ管道循环的文章非常好,可以找到here(虽然这是一个老问题,所以希望未来的读者会受益!)。
答案 5 :(得分:0)
你在想这样的事吗?
public class YourObject{
public List<OtherObject> Others { get; set; }
}
public class OtherObject{
public void DoIt(){}
}
var theList = new List<YourObject>();
theList.ForEach(yo => yo.Others.ForEach(oo => oo.DoIt()));
答案 6 :(得分:0)
我建议您在循环遍历的第二件事中创建一个Dictionary
。然后在foreach
内部,只需将Dictionary
用作所需值的查找即可。
已更新,其中嵌入了foreach
和Dictionary
替代示例:
List<ItemA> itemAs = new List<ItemA> {
new ItemA { id = 1, number = 10 },
new ItemA { id = 2, number = 15 },
new ItemA { id = 3, number = 20 }
};
List<ItemB> itemBs = new List<ItemB> {
new ItemB { id = 1, rate = 100 },
new ItemB { id = 2, rate = 150 },
new ItemB { id = 3, rate = 200}
};
List<ItemAB> itemABs = new List<ItemAB>();
// embedded foreach
foreach(ItemA itemA in itemAs)
{
foreach(ItemB itemB in itemBs)
{
if(itemA.id == itemB.id)
{
ItemAB itemAB = new ItemAB { id = itemA.id, number = itemA.number, rate = itemB.rate };
itemABs.Add(itemAB);
}
}
}
// using dictionary as lookup
Dictionary<int, ItemB> itemBLookup = itemBs.ToDictionary(x => x.id, y => y);
foreach (ItemA itemA in itemAs)
{
itemBLookup.TryGetValue(itemA.id, out ItemB itemB);
ItemAB itemAB = new ItemAB { id = itemA.id, number = itemA.number, rate = itemB.rate };
itemABs.Add(itemAB);
}