6

Suppose we have a

var dictionary= new Dictionary<int, IList<int>>();

What I want is to ouput a sorted version of it, ordered first by keys and then by values inside a list.

E.g.

1   2, 1, 6
5   2, 1
2   1, 3

Becomes

1    1, 2, 6
2    1, 3
5    1, 2

I tried doing it inside foreach, but obviously this is a bad idea to change the thing you are iterating.

Dave M
  • 1,302
  • 1
  • 16
  • 28
Yurii Hohan
  • 4,021
  • 4
  • 40
  • 54
  • 1
    "I want to get is a sorted version" - _how_ do you want it? As output, or as a new collection? – H H Feb 14 '12 at 12:42

4 Answers4

12

Try this:

    // Creating test data
    var dictionary = new Dictionary<int, IList<int>>
    {
        { 1, new List<int> { 2, 1, 6 } },
        { 5, new List<int> { 2, 1 } },
        { 2, new List<int> { 2, 3 } }
    };

    // Ordering as requested
    dictionary = dictionary
        .OrderBy(d => d.Key)
        .ToDictionary(
            d => d.Key,
            d => (IList<int>)d.Value.OrderBy(v => v).ToList()
        );

    // Displaying the results
    foreach(var kv in dictionary)
    {
        Console.Write("\n{0}", kv.Key);
        foreach (var li in kv.Value)
        {
            Console.Write("\t{0}", li);
        }
    }
Schiavini
  • 2,869
  • 2
  • 23
  • 49
  • This is wrong for two reasons. One, by putting them back to a dictionary, you're again corrupting his preferred order. Two, you cannot cast an `IOrderedEnumerable` to `IList`. – nawfal May 20 '14 at 07:36
  • We missed the ToList call, indeed. The order is kept though. – Schiavini May 20 '14 at 08:28
  • fine. But still, by calling `ToDictionary` in the end, you're putting the items back to an unordered collection. The "working" part is coincidental, its not documented. The implementation might change. The thing to remember is that **dictionary is by definition an unordered collection**. [See](http://stackoverflow.com/questions/1453190/does-the-enumerator-of-a-dictionarytkey-tvalue-return-key-value-pairs-in-the) – nawfal May 20 '14 at 08:33
3

A Dictionary is unsorted. To sort a dictionary you can use the OrderedDictionary.

To sort the lists, you can use List<T>.OrderBy()

Dennis Traub
  • 50,557
  • 7
  • 93
  • 108
  • 1
    -1: Does not answer the question, read again. The OP does not want to sort the dictionary, he/she only want to output it sorted. – leppie Feb 14 '12 at 12:41
  • @leppie I read again. And still OP explicitly says he/she wants a "sorted version of it". A sorted version of a dictionary is, well, go and guess. Thanks for the downvote anyway. – Dennis Traub Feb 14 '12 at 12:46
3

You can use LINQ to order the contents of the dictionary like this:

        var dictionary = new Dictionary<int, IList<int>>();
        var orderedItems = dictionary
                               .OrderBy(pair => pair.Key)
                               .Select(new {
                                        Key = pair.Key, 
                                        Value = pair.Value.OrderBy(i => i)});

Of course, this is rather ugly. A better option at this point is to use LINQ syntax

            var orderedItems =from pair in dictionary
                  orderby pair.Key
                  let values = pair.Value.OrderBy(i => i)
                  select new { Key = pair.Key, Value = values };

If you need to use the resulting IEnumerable as a list or array, you can create one using ToList or ToArray. In most cases though, you can just use the IEnumerable as it is

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
0

You can loop through the dictionary items and sort each list seperately. it will look like this:

SortDictionary(dictionary);

after that:

foreach (System.Collections.Generic.KeyValuePair<int,IList<int>> list in dictionary)
        { 
            SortDictionary( list.Value)
        }
Ozgur Dogus
  • 911
  • 3
  • 14
  • 38