2010-03-03 4 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(); 
} 

I는 예시의 문제점을 설명 할 것이다 :

나는 사전에 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" }); 

나는이 개 항목을 제거

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

는 지금은 2 개 다른 항목을 추가 할 : 나는 "요소 1", "요소 2, 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" }); 

","요소 3, 2 부 "

있지만 다음과 같은 순서로 실제로 : ", 요소 1 ","요소 3, 2 부 ","요소 2 제 2 부 "


,

나는 이러한 항목의 순서에 따라 결정됩니다. 왜 그것이 예상대로 아니며 어떻게해야합니까?

+0

예, 북마크를 가져옵니다. :) –

답변

0

찾고있는 것 같아 그것과 KeyedCollection은 요소의 SequenceNo 속성을 수동으로 압축하는 목적을 상실합니다.

은 엄밀히 내 솔루션은 예쁜하지 않기 때문에 우리는 순서가 발생하는 방식을 재 작성해야, 말하기 : 항목이 삭제 될 때마다, 사전을 새와 newed 사전에 삭제되지 않은 항목을 다시 추가

디폴트 순서를 유지하기 위해서. -> 끔찍한 연습이라고 인정합니다. 압력을 줄이자 마자 그것을 바꿀 계획을 세우십시오.

14

.Net 사전은 의도적으로 정렬되지 않습니다.

대신 KeyedCollection<TKey, TValue>을 사용해야합니다. 항목이 콜렉션에 추가되는 순서를 보존하며 빠른 검색을 위해 해시 표를 사용합니다. 예를 들어

: 항목이 컬렉션에 추가 된 후에는 Id 속성을 변경하는 경우, 당신이 컬렉션에 ChangeItemKey 메소드를 호출해야한다는 점

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 속성을 읽기 전용으로 설정하는 것이 좋습니다.

3

당신이하는 System.Collections.Generic.SortedDictionary를 사용하지 않는 이유 모든 이유는 SortedDictionary 우리가 저장해야 할 데이터의 엄청난 양에 대한 빠른 것만으로는 충분하지 않습니다 당신이 불행하게도

관련 문제