ibininja ibininja - 21 days ago 7
C# Question

Sorting Dictionary <string, List<int>> based on value

I have a dictionary of string as key and an ordered List of Integers List as Values; Is it possible to have it ordered based on order of values in c#?

For example:
myDict :

{
"hp",<10,14,23>
"dell", <6,8,9,10>
"asus", <6,9,18>
"mac", <7,98>
}


Sorted as:

{
"dell", <6,8,9,10>
"asus", <6,9,18>
"mac", <7,98>
"hp",<10,14,23>
}


Here is what I have tried:

//this creates a dictionary with requirements stated above for testing
Dictionary<string, List<int>> myDict = new Dictionary<string, List<int>
>();


var numbers = "8,13,16,21,24,25,31,33,36,63,66,70,76,82,94".Split(',').Select(Int32.Parse).ToList();
myDict .Add("asus", numbers);

numbers = "6,84,90,99".Split(',').Select(Int32.Parse).ToList();
myDict .Add("dell", numbers);

numbers = "10,11,20,21,23,26,28,29,31,38,39,40,50,52,61,65,66,70,75,94".Split(',').Select(Int32.Parse).ToList();
myDict.Add("hp", numbers);

numbers = "4,17,42,56,62,79,80".Split(',').Select(Int32.Parse).ToList();
myDict .Add("mac",numbers );


The part that is suppose to do the sorting:

var orderedDictionary = myDict.OrderByDescending(pairs => pairs.Value);


The above gives an error of "At least one object must implement IComparable."
I have also tried converting the list to string and doing the following:

var sortedDict = from entry in myDict
orderby entry.Value
ascending
select entry;


The above worked however it treats numbers as strings; hence 10,85 would appear before 8,6 I am guessing it is because "," ASCII representation is higher than numbers.

How do I come to sort a dictionary with sorted list of integers in c#? or the only way to do a manual sorting by checking each cell over the other cells?

Answer

You should implement IComparer<T> for your List<int>:

public MyListComparer : IComparer<List<int>>
{
    public int Compare(List<int> x, List<int> y)
    {
        var minLength = x.Length < y.Length? x.Length : y.Length;
        for (var i = 0 ;i < minLength; i++)
        {
            if (x[i] > y[i])
            {
                return 1;
            }
            if (x[i] < y[i])
            {
                return -1;
            }
        }
        if (x.Length > y.Length)
        {
            return 1;
        }
        if (y.Length > x.Length)
        {
            return -1;
        }
        return 0;
    }
}

And use it with this overload of LINQ OrderBy :

var orderedDictionary = myDict.OrderBy(pairs => pairs.Value, new MyListComparer());
Comments