Изменить количество элементов в словаре C#

У меня есть словарь, что-то вроде

Dictionary<Foo,String> fooDict

Я просматриваю все в словаре, например

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

Он делает это в том порядке, в котором foo были добавлены в словарь, поэтому первый добавленный элемент - это первый возвращенный foo.

Как я могу изменить количество элементов, чтобы, например, третий добавленный foo был вторым возвращенным foo? Другими словами, я хочу изменить его «индекс».

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
4 646
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Я не полностью обучен в данной области, чтобы правильно ответить на вопрос, но у меня есть чувство, что словарь сортирует значения в соответствии с ключом, чтобы выполнить быстрый поиск ключа. Это предполагает, что словарь отсортирован по ключевым значениям в соответствии с ключевым сравнением. Однако, глядя на методы объект, я предполагаю, что они используют хэш-коды для сравнения различных объектов, учитывая, что нет требований к типу, используемому для ключей. Это только предположение. Кто-то более осведомленный должен заполнить более подробную информацию.

Почему вы заинтересованы в манипулировании «индексом» словаря, когда его цель - индексировать произвольные типы?

Мой словарь на самом деле Dictionary <ListViewItem, CustomObject>. Я хочу сделать так, чтобы когда пользователь переупорядочивал элементы в списке, он также переупорядочивал элементы в словаре, чтобы они выходили в том же порядке.

Asmor 25.09.2008 03:46
Ответ принят как подходящий

Если вы прочитаете документацию на MSDN, вы увидите следующее:

«Порядок возврата товаров не определен».

Вы не можете оценить порядок, потому что Словарь - это не список или массив. Он предназначен для поиска значения по ключу, и любая возможность перебирать значения - это просто удобство, но порядок - это не поведение, от которого вы должны зависеть.

В .NET есть альтернативный объект, который позволяет поддерживать порядок в справочнике, см .: stackoverflow.com/questions/130614#130911

Eric Schoonover 25.09.2008 05:11

Не знаю, пригодится ли это кому-нибудь, но вот что я выяснил. Кажется, он работает (я имею в виду, что он не генерирует никаких исключений), но я все еще далек от возможности проверить, работает ли он так, как я надеюсь. Однако я делал подобное раньше.

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

Вы "вероятно" в порядке, но, как я уже сказал, заказ не будет гарантирован. Бьюсь об заклад, что в тот момент, когда ему нужно изменить размер, он переупорядочит все в попытке. Почему ты вообще пользуешься словарем?

CodeRedick 25.09.2008 05:10

Желание связать элемент просмотра списка с настраиваемым объектом. Я уже делал это несколько раз в проекте, над которым работаю, но это первый раз, когда мощность действительно имеет значение.

Asmor 25.09.2008 05:20

Короткий ответ заключается в том, что способа быть не должно, поскольку Словарь «представляет собой набор ключей и значений». что не подразумевает какого-либо порядка. Любой взлом, который вы можете найти, выходит за рамки определения класса и может быть изменен.

Вы, вероятно, сначала должны спросить себя, действительно ли словарь нужен в этой ситуации, или вы можете обойтись без использования List of 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();
    }

Обновлено: Почему-то не дает мне прокомментировать свой ответ.

В любом случае, IndexableDictionary отличается от OrderedDictionary тем, что

  1. «Элементы OrderedDictionary никак не сортируются». Поэтому foreach не обращает внимания на числовые индексы
  2. Он строго типизирован, поэтому вам не нужно возиться с приведением вещей из структур DictionaryEntry.

Разве это не воссоздание OrderedDictionary?

Eric Schoonover 25.09.2008 05:12

@ Spok16: он строго типизирован (нет снижения производительности упаковки / распаковки / других проблем), и к нему можно получить доступ с помощью индексов.

Callum Rogers 23.07.2009 02:04

Возможно, вас заинтересует класс OrderedDicationary, который входит в пространство имен System.Collections.Specialized.

Если вы посмотрите на комментарии в самом низу, кто-то из MSFT опубликовал эту интересную заметку:

This type is actually misnamed; it is not an 'ordered' dictionary as such, but rather an 'indexed' dictionary. Although, today there is no equivalent generic version of this type, if we add one in the future it is likely that we will name such as type 'IndexedDictionary'.

Я думаю, было бы тривиально унаследовать от этого класса и создать общую версию OrderedDictionary.

Вау, я даже не подозревал, что такое существовало. Спасибо!

Asmor 25.09.2008 05:24

Другие вопросы по теме