0

I need to know if there is any way of ordering an IDictionary without knowing what type it is exactly ...

For example, I have a method that received an object and within this I have a Dictionary object ... all I know is that it is a Dictionary so I can do this:

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

but need sort the items of this Dictionary by EnumPersonalizado regardless of what the other Type "something?" has

Maicon
  • 51
  • 10

4 Answers4

4

You can't sort a dictionary. A dictionary, by definition, doesn't have an "order" of the items within it. The items are stored in some mechanism that is beyond your control that is designed to make it as efficient as possible for adding, removing, and searching.

The best that you can do is take all of the items out of the dictionary, put them in some other sort of collection, and then sort that.

As to your particular case, it's not clear to us what the type of the key or the value in the dictionary is, and that would need to be known in order to be able to try to sort the data.

Servy
  • 202,030
  • 26
  • 332
  • 449
1

see this question. Dictionaries by themselves don't have an index order. Consider inheriting from the KeyedCollection class instead. It's a merge of a dictionary and an ordinary list, and it's designed to use a member of your items as the key, and have an index order.

Community
  • 1
  • 1
1

There are plenty of legitimate reasons to want to apply a partial ordering to dictionaries based on key, it isn't a fundamental quality that keys be unordered, only that a given key will yield a given value.

That being said, if you find yourself with a non-generic IDictionary, it can actually be quite troublesome to 'sort' by key without knowledge of the key type. In my specific scenario, I wanted a function which would transform an IDictionary into another IDictionary where the entries could be enumerated by the ordered keys.

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

This will construct a new dictionary instance, such that traversals (foreach) will visit the entries based on the sort order of the keys.

The oddly named SortedList can be found in System.Collections and orders keys using the ÌComparable interface.

Robert Byrne
  • 562
  • 2
  • 13
  • Inserting a bunch of data into a `SortedList` is a *very* inefficient way of sorting data. Inserting N items into a sorted list is an O(n^2) operation, whereas any sensible sort is going to be an O(n*log(n)) operation. .NET offers *tons* of ways of sorting information, such as LINQ's `OrderBy` (which is probably the easiest in this context). – Servy Jun 13 '14 at 18:20
  • That's a good point, I should have mentioned that in my case I needed an IDictionary on the other end as well. – Robert Byrne Jun 17 '14 at 21:50
  • It generally doesn't really make sense to need your data structure to be both sorted and a way to look up values from a key, but if that is what you need, then use a `SortedDictionary`. – Servy Jun 18 '14 at 13:39
  • @Servy I didn't need to have a constantly ordered collection at runtime. I only needed to materialize a sorted dictionary immediately before serialization. Also, all I had was a non-generic `IDictionary`, with no knowledge of key type. To avoid a lot of reflection (which it seems the OP resorted to) I needed an old style collection from the pre-generic days, which rules out `SortedDictionary`. `SortedList` just happened to fit all these requirements nicely, I believe it may be of use to someone in this (admittedly) narrow scenario, but I will edit the question to clarify. – Robert Byrne Jun 18 '14 at 15:42
-2

IDictionary is IEnumerable, so you can try to do something like new ArrayList(dictionary).Sort(), but it will try to cast members to IComparable, or you can use a Sort overload which accepts an IComparer object. Another way is to use a reflection - first you find actual Keys/Values types and then you create a call to generic OrderBy.

dead_ant
  • 124
  • 4
  • The entire concept of sorting a dictionary doesn't make sense. A dictionary is, by definition, unordered. – Servy Feb 15 '13 at 16:22
  • 1
    @Servy Which does not prohibit that we would like to display the contents in some order logical to the user. – Oskar Berggren Feb 15 '13 at 17:02
  • well in the end had to choose to do it by reflection, I separated the dictionary into two lists, one IList with the keys and IList with values ​​and I did a loop manually ordering was a very messy code but found no other option ... thank you – Maicon Feb 15 '13 at 19:00
  • @Maicon - I'm sure there's a less messy way to do it, but you didn't give us enough information to help. See all the questions asked in the comments above. – Bobson Feb 15 '13 at 19:46