C#优化嵌套的foreach循环

时间:2018-11-24 09:18:10

标签: c# linq

我写了一个库,该库可与大型excel一起使用,并将条目映射到对象中。但是在某些时候,由于三个嵌套的foreach循环,它变得非常慢。我看过字典的一些解决方案,但问题与我的有所不同。

var house = new PostHouse();
house.FK_STRID = long.Parse(fields[2]);
if (!fields[3].Equals("")){
     house.HouseNumber = long.Parse(fields[3]);
}
foreach (var canton in cantons)
{
    foreach(var city in canton.Cities)
    {
        if (city.Streets == null) 
            city.Streets = new List<PostStreet>();
        foreach(var street in city.Streets)
        {
            if(street.STRID == house.FK_STRID)
            {
                if (street.Houses == null) 
                    street.Houses = new List<PostHouse>();
                street.Houses.Add(house);
            }
        }
    }
}

遍历所有内容大约需要10分钟。

有帮助吗?

预先感谢

2 个答案:

答案 0 :(得分:2)

很难说,因为我们不知道NS_ASSUME_NONNULL*是什么类型及其子代以及它们的来源,但是这里的主要问题是您的数据结构不适合该任务。您需要一个州内城市内部街道的分层列表,当您需要的是按STRID为索引的街道列表时。

如果您可以对街道的存储方式进行初始处理,则可以执行以下操作:

cantons

然后,当您在O(1)时间内遍历房屋时,可以立即通过STRID查找街道。

var streetIndex = new Dictionary<string, PostStreet>();
foreach (var canton in cantons)
  foreach (var city in canton.Cities)
    foreach (var street in city.Streets)
    { 
        streetIndex.Add(street.STRID, street);
    }

答案 1 :(得分:0)

在您的构造函数中执行此操作或自动初始化它们

Streets = new List<PostStreet>();

...

Houses = new List<PostHouse>()

然后是Linq

var streets = cantons.SelectMany(x => x.Cities)
                     .SelectMany(x => x.Streets)
                     .Where(x => x.STRID == house.FK_STRI);


foreach (var street in streets)
    street.Houses.Add(house);