문제

나한테는 사전 같은 게 있어요

Dictionary<Foo,String> fooDict

나는 사전에 있는 모든 것을 단계별로 살펴봅니다.

foreach (Foo foo in fooDict.Keys)
    MessageBox.show(fooDict[foo]);

foos가 사전에 추가된 순서대로 수행되므로 추가된 첫 번째 항목이 첫 번째 foo가 반환됩니다.

예를 들어 세 번째 foo가 추가되면 두 번째 foo가 반환되도록 카디널리티를 어떻게 변경할 수 있습니까?즉, "색인"을 변경하고 싶습니다.

도움이 되었습니까?

해결책

MSDN의 문서를 읽으면 다음을 볼 수 있습니다.

"품목이 반환되는 순서는 정의되지 않았습니다."

사전은 목록이나 배열이 아니기 때문에 주문을 할 수는 없습니다. 그것은 열쇠에 의해 값을 찾아야하며, 값을 반복하는 능력은 편의성 일 뿐이지 만 순서는 당신이 의존 해야하는 행동이 아닙니다.

다른 팁

당신은 다음에 관심이있을 수 있습니다 OrderedDicationary 들어오는 수업 System.Collections.Specialized 네임스페이스.

맨 아래의 댓글을 보면 MSFT의 누군가가 다음과 같은 흥미로운 메모를 게시했습니다.

이 유형은 실제로 이름이 잘못되었습니다.이는 '순서가 지정된' 사전이 아니라 '인덱스된' 사전입니다.현재는 이 유형에 해당하는 일반 버전이 없지만 나중에 추가하면 'IndexedDictionary' 유형과 같은 이름을 지정할 가능성이 높습니다.

이 클래스에서 파생되어 OrderedDictionary의 일반 버전을 만드는 것은 쉽지 않을 것이라고 생각합니다.

그래요 도메인에서 완전히 교육되지 않았습니다 질문에 올바르게 대답하기 위해서는 있지만 느낌 사전은 빠른 키 검색을 수행하기 위해 키에 따라 값을 정렬합니다. 이는 사전이 주요 비교에 따라 주요 값으로 정렬되었음을 시사합니다. 그러나보고 있습니다 물체 메소드, 나는 그들이 키에 사용되는 유형에 대한 요구 사항이 없다는 것을 고려하여 다른 객체를 비교하기 위해 해시 코드를 사용한다고 가정합니다. 이것은 단지 추측 일뿐입니다. 더 많은 지식이 더 자세하게 채워야합니다.

목적이 임의의 유형으로 색인화 될 때 사전의 "색인"을 조작하는 데 관심이있는 이유는 무엇입니까?

누군가가 이것을 유용하게 생각하는지 모르겠지만 여기에 내가 알아내는 것이 있습니다. 그것은 작동하는 것 같습니다 (예외를 던지지 않는다는 것을 의미합니다). 그러나 나는 여전히 그것이 원하는대로 작동한다는 것을 테스트 할 수있는 방법을 멀리하고 있습니다. 그래도 나는 전에 비슷한 일을 해냈습니다.

        public void sortSections()
    {
        //OMG THIS IS UGLY!!!
        KeyValuePair<ListViewItem, TextSection>[] sortable = textSecs.ToArray();
        IOrderedEnumerable<KeyValuePair<ListViewItem, TextSection>> sorted = sortable.OrderBy(kvp => kvp.Value.cardinality);

        foreach (KeyValuePair<ListViewItem, TextSection> kvp in sorted)
        {
            TextSection sec = kvp.Value;
            ListViewItem key = kvp.Key;

            textSecs.Remove(key);
            textSecs.Add(key, sec);
        }
    }

짧은 대답은 사전이 "키와 값의 모음을 나타내는"방식이 없어야한다는 것입니다. 어떤 종류의 주문도 암시하지 않습니다. 당신이 찾을 수있는 해킹은 클래스의 정의를 벗어나고 변경하기 쉽습니다.

이 상황에서 사전이 실제로 요구되는지 또는 keyvaluepairs 목록을 사용하여 도망 갈 수 있는지 먼저 스스로에게 물어봐야합니다.

그렇지 않으면 이와 같은 것이 유용 할 수 있습니다.

public class IndexableDictionary<T1, T2> : Dictionary<T1, T2>
{
    private SortedDictionary<int, T1> _sortedKeys;

    public IndexableDictionary()
    {
        _sortedKeys = new SortedDictionary<int, T1>();
    }
    public new void Add(T1 key, T2 value)
    {
        _sortedKeys.Add(_sortedKeys.Count + 1, key);
        base.Add(key, value);
    }

    private IEnumerable<KeyValuePair<T1, T2>> Enumerable()
    {
        foreach (T1 key in _sortedKeys.Values)
        {
            yield return new KeyValuePair<T1, T2>(key, this[key]);
        }
    }

    public new IEnumerator<KeyValuePair<T1, T2>> GetEnumerator()
    {
        return Enumerable().GetEnumerator();
    }

    public KeyValuePair<T1, T2> this[int index]
    {
        get
        {
            return new KeyValuePair<T1, T2> (_sortedKeys[index], base[_sortedKeys[index]]);
        }
        set
        {
            _sortedKeys[index] = value.Key;
            base[value.Key] = value.Value;
        }

    }


}

클라이언트 코드를 사용하면 다음과 같이 보입니다.

    static void Main(string[] args)
    {
        IndexableDictionary<string, string> fooDict = new IndexableDictionary<string, string>();

        fooDict.Add("One", "One");
        fooDict.Add("Two", "Two");
        fooDict.Add("Three", "Three");

        // Print One, Two, Three
        foreach (KeyValuePair<string, string> kvp in fooDict)
            Console.WriteLine(kvp.Value);



        KeyValuePair<string, string> temp = fooDict[1];
        fooDict[1] = fooDict[2];
        fooDict[2] = temp;


        // Print Two, One, Three
        foreach (KeyValuePair<string, string> kvp in fooDict)
            Console.WriteLine(kvp.Value);

        Console.ReadLine();
    }

업데이트: 어떤 이유로 든 내 자신의 대답에 대해 언급하지 않을 것입니다.

어쨌든, 색인형은 질서와는 다릅니다

  1. "질서의 요소는 어떤 식 으로든 분류되지 않습니다." 그래서 Foreach 's는 수치 지수에주의를 기울이지 않을 것입니다.
  2. 그것은 강하게 입력되므로 사전에서 물건을 던지는 것을 엉망으로 만들 필요가 없습니다.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top