2010-03-03 62 views
5

我有一個Dictionary<Guid, ElementViewModel>。 (ElementViewModel是我們自己的複雜類型。) 我將項目添加到庫存標準的字典中items.Add(Guid.NewGuid, new ElementViewModel() { /*setters go here*/ });有沒有辦法跟蹤字典中項目的排序?

在稍後階段,我刪除部分或全部這些項目。

我ElementViewModel的簡單化的看法是這樣的:

class ElementViewModel 
{ 
    Guid Id { get; set; } 
    string Name { get; set; } 
    int SequenceNo { get; set; } 
} 

可能顯著一提的是SequenceNos被添加後的集合中壓實,以防其他操作,如移動和複製的發生。 {1,5,6} - > {1,2,3}

我的刪除操作的簡單化的觀點是:

public void RemoveElementViewModel(IEnumerable<ElementViewModel> elementsToDelete) 
{ 
    foreach (var elementViewModel in elementsToDelete) 
     items.Remove(elementViewModel.Id); 

    CompactSequenceNumbers(); 
} 

我將說明用一個例子的問題:

我加3項詞典:

var newGuid = Guid.NewGuid(); 
items.Add(newGuid, new MineLayoutElementViewModel { Id = newGuid, SequenceNo = 1, Name = "Element 1" }); 
newGuid = Guid.NewGuid(); 
items.Add(newGuid, new MineLayoutElementViewModel { Id = newGuid, SequenceNo = 2, Name = "Element 2" }); 
newGuid = Guid.NewGuid(); 
items.Add(newGuid, new MineLayoutElementViewModel { Id = newGuid, SequenceNo = 3, Name = "Element 3" }); 

我刪除了2項

RemoveElementViewModel(new List<ElementViewModel> { item2, item3 }); //imagine I had them cached somewhere. 

現在我想添加其他2項:

newGuid = Guid.NewGuid(); 
items.Add(newGuid, new MineLayoutElementViewModel { Id = newGuid, SequenceNo = 2, Name = "Element 2, Part 2" }); 
newGuid = Guid.NewGuid(); 
items.Add(newGuid, new MineLayoutElementViewModel { Id = newGuid, SequenceNo = 3, Name = "Element 3, Part 2" }); 

在此時詞典的評價,我預計項目爲了 「元件1」,「元素2,第2部分」, 「元素3,第2部分」

但它實際上是按以下順序: 「元件1」, 「元素3,第2部分」, 「元件2,第2部分」


我依靠這些項目的順序是一定的方式。爲什麼它不如預期,我能做些什麼呢?

+0

當然,得到一些書籤:) – 2010-03-03 16:19:39

回答

0

不幸的是什麼,一個SortedDictionary是速度不夠快,我們必須存儲的數據量巨大在它裏面,一個KeyedCollection失敗了手動壓縮元素的SequenceNo屬性的目的。

嚴格地說,我們應該重寫測序發生的方式,因爲我的解決方案是不是最漂亮的:

每一個項目被刪除時,新的字典和非刪除的項目重新添加到newed詞典以保持默認順序。 - >可怕的做法,我承認。計劃在我減輕壓力時立即改變它。

14

.Net字典是由設計無序的。

您應該改用KeyedCollection<TKey, TValue>;它將保留項目添加到集合的順序,並且還將使用散列表進行快速查找。

例如:

class ElementViewModelCollection : KeyedCollection<Guid, ElementViewModel> { 
    protected override Guid GetKeyForItem(ElementViewModel item) { return item.Id; } 
} 

items.Add(new MineLayoutElementViewModel { Id = Guid.NewGuid(), SequenceNo = 3, Name = "Element 3" }); 

請注意,如果你改變了Id屬性的項目添加到集合後,你需要呼籲集合ChangeItemKey方法。我強烈建議您將Id屬性設置爲只讀。

3

你爲什麼不使用System.Collections.Generic.SortedDictionary,任何理由好像你正在尋找

相關問題