1

I have tried to sort a Dictionary object by value which is generic.

Here is my code

Dictionary<string, ReportModel> sortedDic = new Dictionary<string, ReportModel>();
Dictionary<string, ReportModel> rDic = new Dictionary<string, ReportModel>();
var ordered = sortedDic.OrderByDescending(x => x.Value.totalPurchase);
foreach (var item in ordered)
{                           
    rDic.Add(item.Key, item.Value);
}

The variable, ordered, just has the same order like sortedDic. What is wrong with this? Any idea?

user1713153
  • 219
  • 5
  • 12
  • 1
    What type is totalPurchase? – Luis Filipe May 26 '13 at 23:00
  • What's the error do u get ? – cat916 May 26 '13 at 23:02
  • How do you add the items to 'sortedDic'? Does it happen to be from highest to lowest totalPurchase? – Luis Filipe May 26 '13 at 23:02
  • 2
    You're setting yourself up for confusion by calling a Dictionary "sortedDic", when, by definition, a Dictionary should be treated as an unsorted set... e.g. there is no implicit sort order. It won't matter what order you insert them into rDic, it will only partially affect the order of rDic, and any such ordering is unspecified and can't be relied upon. – spender May 26 '13 at 23:03

2 Answers2

4

This happens because Dictionary is generally an unordered container*. When you put the data into rDic, it becomes unordered again.

To retain the desired order, you need to put the results into a container that explicitly keeps the ordering that you supply. For example, you could use a list of KeyValuePair<string,ReportModel>, like this:

IList<KeyValuePair<string,ReportModel>> ordered = sortedDic
    .OrderByDescending(x => x.Value.totalPurchase)
    .ToList();


* Due to the way the Dictionary<K,V> is implemented by Microsoft, it happens to retain the insertion order, but that is incidental and undocumented, so it may change in the future versions, and should not be relied upon.
Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • I tested the above code and it worked in my scenario. Was i just lucky? – Luis Filipe May 26 '13 at 23:09
  • 1
    @LuisFilipe That's no luck, it's an undocumented implementation detail that I mentioned in the footnote to the answer ([click this link for more info of what is going on there](http://stackoverflow.com/a/976871/335858)). – Sergey Kalinichenko May 26 '13 at 23:16
  • @user1713153 You are welcome! If you are no longer actively looking for an improved solution, you may want to accept the answer to indicate that it has worked for you. – Sergey Kalinichenko May 27 '13 at 10:54
0

When adding the items back to the dictionary, it would not keep their order. You can either:

  1. Use the following implementation.
  2. Use a list in the below form.

    IEnumrable> lst=
       sortedDic.OrderByDescending(x => x.Value.totalPurchase).ToArray();
  3. [EDIT] If you don't mind the key changing then you can use SortedDictionary<,>.

WhyMe
  • 535
  • 2
  • 13