2012-08-15 48 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" 
}