2012-08-15 46 views
6

我找不到这个的具体例子,所以我发布的问题。任何帮助赞赏。比较两个大的通用名单

我有两个大的通用列表,都有超过300K项目。

我正在循环第一个列表以回收信息,并为动态生成新列表生成一个新项目,但是我需要在第二个列表中搜索并根据三个匹配条件返回一个值,如果找到要添加到列表中,但正如你可以想象的那样,做这个300k * 300k次需要时间。

有什么办法可以更有效地做到这一点?

我的代码:

var reportList = new List<StocksHeldInCustody>(); 
foreach (var correctDepotHolding in correctDepotHoldings) 
    { 
    var reportLine = new StocksHeldInCustody(); 
    reportLine.ClientNo = correctDepotHolding.ClientNo; 
    reportLine.Value = correctDepotHolding.ValueOfStock; 
    reportLine.Depot = correctDepotHolding.Depot; 
    reportLine.SEDOL = correctDepotHolding.StockCode; 
    reportLine.Units = correctDepotHolding.QuantityHeld; 
    reportLine.Custodian = "Unknown"; 
    reportLine.StockName = correctDepotHolding.StockR1.Trim() + " " + correctDepotHolding.StockR2.Trim(); 

    //Get custodian info 

    foreach (var ccHolding in ccHoldList) 
    { 
     if (correctDepotHolding.ClientNo != ccHolding.ClientNo) continue; 
     if (correctDepotHolding.Depot != ccHolding.Depot) continue; 
     if (correctDepotHolding.StockCode != ccHolding.StockCode) continue; 
     if (correctDepotHolding.QuantityHeld != ccHolding.QuantityHeld) continue; 
     reportLine.Custodian = ccHolding.Custodian; 
     break; 
    } 
    reportList.Add(reportLine); 
    } 
+0

在对象创建的所有瓦尔的哈希在一起,只检查这些,它必须跑得快那么 – EaterOfCode 2012-08-15 09:28:36

+1

数据的来源是什么?如果它是一个体面的数据库,这可能会做得更好。 – 2012-08-15 09:31:19

+0

更新了我的通用答案,详细介绍了如何在linq中执行外连接 – Arkiliknam 2012-08-16 08:27:59

回答

5

由于Pranay说,一个连接可能是你想要什么:

var query = from correct in correctDepotHoldings 
      join ccHolding in ccHoldList 
       on new { correct.ClientNo, correct.Depot, 
         correct.StockCode, correct.QuantityHeld } 
       equals new { ccHolding.ClientNo, ccHolding.Depot, 
          ccHolding.StockCode, ccHolding.QuantityHeld } 
      // TODO: Fill in the properties here based on correct and ccHolding 
      select new StocksHeldInCustody { ... }; 
var reportList = query.ToList(); 
+0

嗨,即时通讯关键词“等于”和“ccHolding”得到错误,我需要在使用它之前声明这是一个变量? – 2012-08-15 13:58:16

+0

@DavidJohnson:哎呀,忘了“in”部分。看看我的编辑 - 如果你是LINQ的新手,我会放下一些时间来完全学习。 – 2012-08-15 13:59:47

+0

谢谢 - 我在尝试,但它似乎是一些,如果它是随机组成的,没有模式,我猜它只是一个学习学习案例!再次感谢。 – 2012-08-15 14:13:19

3

你可以从查找列表中的数据转移到一个字典,键为3个项目,你正在搜索的一个独特的哈希值。然后,您将可以快速查找并节省数百万次迭代。

3

检查我的全文后:Linq Join on Mutiple columns using Anonymous type

制作使用LINQ内的加盟,会为你做的工作。

var list = (from x in entity 
      join y in entity2 
      on new { x.field1, x.field2 } 
     equals new { y.field1, y.field2 } 
     select new entity { fields to select}).ToList(); 

加入多个领域

enter image description here

EmployeeDataContext edb= new EmployeeDataContext(); 
var cust = from c in edb.Customers 
      join d in edb.Distributors on 
      new { CityID = c.CityId, StateID = c.StateId, CountryID = c.CountryId, 
        Id = c.DistributorId } 
      equals 
      new { CityID = d.CityId, StateID = d.StateId, CountryID = d.CountryId, 
        Id = d.DistributorId } 
      select c; 
+0

该连接语法无效。看到我的答案是一个正确的例子。 – 2012-08-15 09:32:33

+1

@JonSkeet - 刚刚更新.......谢谢先生 – 2012-08-15 09:35:18

1

使用LINQ LINQ的加入列表,并返回它,你怎么样。

var list1 = GetMassiveList(); 
var list2 = GetMassiveList(); 

var list3 = from a in list1 
      join b in list2 
       on new { a.Prop1, a.Prop2 } equals 
        new { b.Prop1, b.Prop2 } 
      select new { a.Prop1, b.Prop2 }; 

做你outter加入,你可以使用DefaultIfEmpty() 这个例子设置你的右侧部分的连接,为案件默认对象(通常为空),其中加入WASN没有。

from a in list1 
join b in list2 
    on new { a.Prop1, a.Prop2 } equals 
     new { b.Prop1, b.Prop2 } 
into outer 
from b in outer.DefaultIfEmpty() 
select new 
    Prop1 = a.Prop1, 
    Prop2 = b != null ? b.Prop2 : "Value for Prop2 if the b join is null" 
}