Сортировка IDictionary Generic

Мне нужно знать, есть ли способ заказать IDictionary, не зная, какой именно это тип...

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

public void MyMethod(PropertyInfo propriedadeParametro, object parameters){
   IDictionary dictionary = ((IDictionary) propriedadeParametro.GetValue (parameters, null));
}

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


person Maicon    schedule 15.02.2013    source источник
comment
Что такое EnumPersonalizado? Что такое Something? Опубликуйте свой полный код   -  person LukeHennerley    schedule 15.02.2013
comment
Какова связь EnumPersonalizado со словарем?   -  person Jon    schedule 15.02.2013
comment
Все ли ключи в словаре одного (возможно, неизвестного) типа?   -  person Andre Loker    schedule 15.02.2013
comment
что-нибудь? может быть чем угодно EnumPersonalizado - это Enum... Dictionary‹something,EnumPersonalizado›   -  person Maicon    schedule 15.02.2013
comment
И вы хотите, чтобы записи отсортировались по something? Что делать, если в словаре есть разные типы чего-то? Как сравнить машину, собаку и понедельник?   -  person Andre Loker    schedule 15.02.2013
comment
stackoverflow.com/ вопросы/2552928/   -  person    schedule 15.02.2013
comment
мне нужно сравнить EnumPersonalizado... как OrderBy(x=›x.EnumPersonalizado)   -  person Maicon    schedule 15.02.2013


Ответы (4)


IDictionary — это IEnumerable, поэтому вы можете попытаться сделать что-то вроде new ArrayList(dictionary).Sort(), но он попытается преобразовать элементы в IComparable, или вы можете использовать перегрузку Sort, которая принимает объект IComparer. Другой способ — использовать отражение: сначала вы находите фактические типы Keys/Values, а затем создаете вызов универсального OrderBy.

person dead_ant    schedule 15.02.2013
comment
Вся концепция сортировки словаря не имеет смысла. Словарь по определению неупорядочен. - person Servy; 15.02.2013
comment
@Servy Что не запрещает отображать содержимое в каком-то логичном для пользователя порядке. - person Oskar Berggren; 15.02.2013
comment
ну, в конце концов, пришлось сделать это путем отражения, я разделил словарь на два списка, один IList‹object› с ключами и IList ‹EnumPersonalizado› со значениями, и я сделал цикл вручную, упорядочивание было очень беспорядочным кодом но другого варианта не нашел...спасибо - person Maicon; 15.02.2013
comment
@Maicon - я уверен, что есть менее грязный способ сделать это, но вы не предоставили нам достаточно информации, чтобы помочь. Смотрите все вопросы, заданные в комментариях выше. - person Bobson; 15.02.2013

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

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

Что касается вашего конкретного случая, нам не ясно, каков тип ключа или значения в словаре, и это необходимо знать, чтобы попытаться отсортировать данные.

person Servy    schedule 15.02.2013

см. этот вопрос. Словари сами по себе не имеют индексного порядка. Вместо этого рассмотрите возможность наследования от класса KeyedCollection. Это слияние словаря и обычного списка, и он предназначен для использования члена ваших элементов в качестве ключа и имеет порядок индекса.

person Community    schedule 15.02.2013

Есть много законных причин, по которым нужно применить частичное упорядочение к словарям на основе ключа, неупорядоченность ключей не является фундаментальным качеством, а только то, что данный ключ дает заданное значение.

При этом, если вы обнаружите, что у вас не универсальный IDictionary, на самом деле может быть довольно проблематично «сортировать» по ключу, не зная типа ключа. В моем конкретном сценарии мне нужна была функция, которая преобразовывала бы IDictionary в другой IDictionary, в котором записи можно было бы перечислять по упорядоченным ключам.

IDictionary ToSortedDictionary(IDictionary dictionary) {
    return new SortedList(dictionary);
}

Это создаст новый экземпляр словаря, так что обходы (foreach) будут посещать записи в зависимости от порядка сортировки ключей.

Странно названный SortedList можно найти в System.Collections и порядках ключи с помощью интерфейса ÌComparable.

person Robert Byrne    schedule 13.06.2014
comment
Вставка набора данных в SortedListочень неэффективный способ сортировки данных. Вставка N элементов в отсортированный список — это операция O(n^2), тогда как любая разумная сортировка будет операцией O(nlog(n)). .NET предлагает *тонны способов сортировки информации, таких как OrderBy LINQ (который, вероятно, является самым простым в данном контексте). - person Servy; 13.06.2014
comment
Это хороший момент, я должен был упомянуть, что в моем случае мне нужен IDictionary и на другом конце. - person Robert Byrne; 18.06.2014
comment
Как правило, нет смысла требовать, чтобы ваша структура данных была одновременно отсортирована и имела способ поиска значений по ключу, но если это то, что вам нужно, используйте SortedDictionary. - person Servy; 18.06.2014
comment
@Servy Мне не нужно было постоянно заказывать коллекцию во время выполнения. Мне нужно было только материализовать отсортированный словарь непосредственно перед сериализацией. Кроме того, все, что у меня было, было неуниверсальным IDictionary, без знания типа ключа. Чтобы избежать долгих размышлений (к которым, похоже, прибегал ОП), мне нужна была коллекция старого стиля из догенерированных дней, которая исключает SortedDictionary. SortedList просто идеально соответствует всем этим требованиям, я считаю, что это может быть полезно кому-то в этом (по общему признанию) узком сценарии, но я отредактирую вопрос, чтобы уточнить. - person Robert Byrne; 18.06.2014