2016-06-10 46 views
1

我有一個對象列表,其中的對象有一個Guid Id屬性。檢查Hashset中是否存在對象的單一屬性值列表

我也有一個Hashset包含一堆Guid。

檢查列表中的每個對象Guid是否存在於Hashset中的最快方法是什麼,然後更新列表中Object的另一個屬性(如果存在)?如果需要,我可以將Hashset更改爲其他數據類型,但列表必須保持不變。

這裏的類/枚舉

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

var clientResponses = new HashSet<Guid>(); 

var testRecords = new List<Test>(); 

這是我目前正在做

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

「最快的方式」是指從耗時編碼的角度,還是從應用程序的性能角度? –

+5

這似乎是對我來說最好的方法。一個更好的問題是你的性能要求到底是什麼,這是否符合他們的要求?如果確實如此,則無需嘗試對其進行優化。 – juharr

+0

首先你可以寫'test.IsResponded = clientResponses.Contains(test.Id)'。除此之外,我認爲這是最好的解決方案。 – Toxantron

回答

-1

你可以這樣做

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

,或者更簡單地

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

每個找到的值都從HashSet中刪除,因此每次下一次迭代都會更快。當然,它只適用於大量的數據。此外,有必要重新創建一個HashSet。

你也可以試試這個優化(這是假設性IsResponded都默認爲false)

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

這種方法是有利的testRecords集合的大小比HashSet的大小顯著較大,很有可能HashSet中的所有值都與此集合中的值一致。在查找全部的情況下,沒有理由繼續迭代該集合。所以,打破循環。

+0

你正在銷燬他的HashSet沒有真正的收益,他可能需要HashSet完成更新他的清單後。至於性能方面的考慮,Contains在HashSet上已經是O(1)操作。此外,刪除是一個O(1)操作,因此每次刪除後應該加快的陳述不具有真正的優點。 –

+0

@AnthonyPegram - 我提到需要重新創建HashSet。我同意,只有在完全匹配並且在循環中斷後取消所有ID之後纔有利。 –

相關問題