2016-06-10 23 views
1

Ich habe eine Liste von Objekten, in denen die Objekte eine Guid Id Eigenschaft haben.Prüfe, ob eine Liste von Objekten in Hashset existiert.

Ich habe auch ein Hashset mit einer Reihe von Guids.

Was ist der schnellste Weg, um zu überprüfen, ob jede Guid-Liste in der Liste im Hashset vorhanden ist, und dann eine andere Eigenschaft für das Objekt in der Liste zu aktualisieren, falls sie existiert? Ich habe die Möglichkeit, den Hash-Satz bei Bedarf zu einem anderen Datentyp zu ändern, aber die Liste muss gleich bleiben.

Hier ist die Klassen/enumerable

public class Test 
{ 
public Guid Id {get; set;} 
public bool IsResponded {get; set;} 
} 

var clientResponses = new HashSet<Guid>(); 

var testRecords = new List<Test>(); 

Dies ist, was ich zur Zeit

foreach (var test in testRecords) 
    { 
     if (clientResponses.Contains(test.Id)) 
      test.IsResponded = true; 
    } 
+0

Mit "der schnellste Weg" meinst du aus einer Zeit verbrachte Coding Sicht, oder aus einer Anwendungsleistung ein? –

+5

Das scheint mir der beste Ansatz zu sein. Eine bessere Frage wäre, was genau Ihre Leistungsanforderungen sind und ob sie diese erfüllen. Wenn dies der Fall ist, müssen Sie nicht versuchen, es zu optimieren. – juharr

+0

Zuerst können Sie 'test.IsResponded = clientResponses.Contains (test.Id)' schreiben. Abgesehen davon denke ich, dass dies die bestmögliche Lösung ist. – Toxantron

Antwort

-1

Sie können

foreach (var test in testRecords) 
{ 
    if (clientResponses.Remove(test.Id)) 
     test.IsResponded = true; 
} 

tun so oder

foreach (var test in testRecords) 
{ 
    test.IsResponded = clientResponses.Remove(test.Id); 
} 
, mehr kurz tue

Jeder gefundene Wert wird aus dem HashSet entfernt, sodass jede nächste Iteration schneller wird. Natürlich ist es nur für die sehr großen Datenmengen wert. Außerdem muss ein HashSet neu erstellt werden.

Auch können Sie diese Optimierung versuchen (es wird angenommen, dass die Eigenschaften IsResponded standardmäßig falsch sind)

foreach (var test in testRecords) 
{ 
    if (clientResponses.Remove(test.Id)) 
    { 
     test.IsResponded = true; 
     if (clientResponses.Count == 0) 
      break; // the remaining IsResponded values will remain unchanged 
    } 
} 

Dieser Ansatz, wenn die Größe der testRecords Sammlung deutlich größer als die Größe des HashSet vorteilhaft ist, und mit hoher Wahrscheinlichkeit stimmen alle Werte aus dem HashSet mit den Werten in dieser Sammlung überein. Wenn alle gefunden werden, gibt es keinen Grund, weiter mit der Sammlung zu iterieren. Also, brich die Schleife.

+0

Du zerstörst sein HashSet für keinen wirklichen Gewinn und er könnte möglicherweise das HashSet benötigen, nachdem er seine Liste aktualisiert hat. Was Leistungsüberlegungen betrifft, ist Contains bereits eine O (1) -Operation auf einem HashSet. Außerdem ist Entfernen eine O (1) -Operation, daher ist Ihre Aussage, dass sie nach jeder Entfernung schneller sein sollte, ohne wirklichen Wert. –

+0

@AnthonyPegram - Ich erwähnte die Notwendigkeit, das HashSet neu zu erstellen. Ich stimme zu, dass es nur nach einem vollständigen Match und dem Entfernen aller Id, nach dem Bruch der Schleife nützlich wäre. –