2011-07-18 46 views
3

我正在尋找一種與通用字典的Keys屬性(類型爲KeyCollection)一樣高效的方法。從KeyedCollection獲取密鑰列表的最有效方法是什麼?

使用LINQ的select語句的工作,但它會在整個集合中的每個請求的關鍵時間迭代,而我相信鍵可能已經被存儲在內部。

目前我GenericKeyedCollection類看起來是這樣的:

public class GenericKeyedCollection<TKey, TItem> : KeyedCollection<TKey, TItem> { 
    private Func<TItem, TKey> getKeyFunc; 

    protected override TKey GetKeyForItem(TItem item) { 
     return getKeyFunc(item); 
    } 

    public GenericKeyedCollection(Func<TItem, TKey> getKeyFunc) { 
     this.getKeyFunc = getKeyFunc; 
    } 

    public List<TKey> Keys { 
     get { 
      return this.Select(i => this.GetKeyForItem(i)).ToList(); 
     } 
    } 
} 

更新:感謝您的回答,我會因此而不是使用LINQ的迭代以下屬性。

public ICollection<TKey> Keys { 
     get { 
      if (this.Dictionary != null) { 
       return this.Dictionary.Keys; 
      } 
      else { 
       return new Collection<TKey>(this.Select(this.GetKeyForItem).ToArray()); 
      } 
     } 
    } 
+0

不相關的確切的問題,但一般KeyedCollections可以TAD更有效。見讀取屬性是此相關http://stackoverflow.com/questions/2154461/is-there-a-better-data-structure-than-dictionary-if-the-values-are-objects-and-a問題 – nawfal

回答

5

按照the documentation,班裏有一個屬性,Dictionary,所以你可以這樣做:

var keys = collection.Dictionary.Keys; 

請注意,有一個警告,如文檔中所述。如果使用字典的閾值構建集合,則至少將很多值放入集合中時纔會填充字典。

如果這不是你的情況,即。字典總是很好去,上面的代碼應該做的伎倆。

如果不是,那麼您必須更改構造以避免設置該閾值,否則您只需循環並通過GetKeyForItem方法提取密鑰。

2

不知道這是最有效的,但你可以使用詞典屬性檢索通用字典表示,然後使用上的鑰匙屬性來獲取密鑰列表。

+1

一個O(1)操作。 –

相關問題