2012-08-15 21 views
6

Nie mogę znaleźć konkretnego przykładu, więc publikuję pytanie. Każda pomoc doceniona.Porównując dwie duże ogólne listy

Mam dwie duże ogólne listy, obie z ponad 300 000 pozycji.

Pętlę przez pierwszą listę, aby pobrać informacje i wygenerować nowy element dla nowej listy w locie, ale muszę przeszukać w ramach drugiej listy i zwrócić wartość, na podstawie TRZECH pasujących kryteriów, jeśli znaleziono aby dodać do listy, jak możesz sobie wyobrazić, zrobienie tego 300k * 300k razy zajmuje trochę czasu.

Czy jest jakiś sposób, aby zrobić to bardziej efektywnie?

Mój kod:

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

utworzyć skrót wszystkich Vars razem w obiekcie i tylko sprawdzić te muszą działać szybko następnie – EaterOfCode

+1

Jakie jest źródło danych? Jeśli jest to przyzwoita baza danych, może to być lepiej zrobione po tej stronie. –

+0

Zaktualizowałem moją ogólną odpowiedź ze szczegółami, jak wykonać sprzężenie zewnętrzne w linq – Arkiliknam

Odpowiedz

5

Jak Pranay mówi sprzężenia jest prawdopodobnie to, co chcesz:

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

Witam, im otrzymuję błędy słowa kluczowego "równa się" i "ccHolding", musiałbym zadeklarować to jako zmienną przed użyciem? –

+0

@DavidJohnson: Ups, zapomniałem o części "w". Zobacz moją edycję - a jeśli dopiero zaczynasz przygodę z LINQ, poświęciłem trochę czasu na naukę. –

+0

Dziękuję- próbuję, ale wygląda na to, że niektóre z nich zostały stworzone losowo bez żadnego schematu, myślę, że to tylko przypadek nauki uczyć się uczyć! Dzięki jeszcze raz. –

3

Można przenieść dane z listy odnośników do słownika, a klucz jest unikalny hash z 3 pozycji szukasz dalej. Wtedy będziesz mieć bardzo szybkie wyszukiwania i zaoszczędzić miliony iteracji.

3

Sprawdź mój cały post: Linq Join on Mutiple columns using Anonymous type

użytkowania czynią LINQ Inner Join że zrobi to za Ciebie.

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(); 

Dołącz LINQ na stwardnienie dziedzinie

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

Ta składnia łączenia jest nieprawidłowa. Zobacz moją odpowiedź na poprawny przykład. –

+1

@JonSkeet - właśnie zaktualizowany ....... dzięki sir –

1

używać LINQ do przyłączenia się do listy i odesłać go jak chcesz.

np

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 }; 

zrobić swoją outter dołączyć, można użyć DefaultIfEmpty() Ten przykład ustawiania prawej części dołączyć do domyślnego obiektu (często null) dla przypadków, w których przyłączyć waśń zrobiony.

np

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" 
}