Question

Please find he attached image.enter image description here

ls is a dicionary<string, string> . I want to sort based on the key. But if the keys are like

7020_1, 7020_23, 7030_5. 7020_8, 7030_1.

I want it to be arranged as

7020_1,7020_8,7020_23,7030_1.7030_5.

let me know the solution.

Was it helpful?

Solution

Here an easy solution.

Dictionary<string, string> d = dic.OrderBy(x => int.Parse(x.Key.Split('_')[0])).ThenBy(x => int.Parse(x.Key.Split('_')[1])).ToDictionary(j => j.Key, j => j.Value);

OTHER TIPS

You should use:

SortedDictionary(Tkey,TValue) and make yours IComparer(T) Interface so it will sort by your own rules.

More on: SortedDictionary and IComparer

Here's a short console app that demonstrates the solution:

class KeyComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        var xSplit = x.Split('_').Select(i => Convert.ToInt32(i)).ToArray();
        var ySplit = y.Split('_').Select(i => Convert.ToInt32(i)).ToArray();
        var diff1 = xSplit[0] - ySplit[0];
        return diff1 != 0 ? diff1 : xSplit[1] - ySplit[1];
    }
}
class Program
{
    static void Main(string[] args)
    {
        var comparer = new KeyComparer();
        var sortedDic = new SortedDictionary<string, object>(comparer)
        {
            {"7020_23", new object()},
            {"7030_1", new object()},
            {"7030_5", new object()},
            {"7020_8", new object()},
            {"7020_1", new object()}
        };

        foreach (var key in sortedDic.Keys)
        {
            Console.WriteLine(key);
        }
    }
}

Output is:

7020_1 
7020_8 
7020_23 
7030_1 
7030_5

Note that this solution assumes that the key is always composed of 2 parts which are parseable as integers, and separated by an underscore.

You need to create your own Comparer to pass to the OrderBy, as you need to do integer comparisons rather than strings. I've used a List, but that doesn't change things.

    static void Main(string[] args)
    {
        var d = new List<string>() { "7020_8", "7030_5", "7020_23", "7020_1", "7030_1" };

        Console.WriteLine("In:");
        foreach (string s in d)
            Console.WriteLine(s);

        Console.WriteLine();

        Console.WriteLine("Sorted Out:");
        foreach (string s in d.OrderBy(f => f, new MyComparer()))
            Console.WriteLine(s);

        Console.ReadLine();
    }

    internal class MyComparer : IComparer<string>
    {

        #region IComparer<string> Members

        public int Compare(string x, string y)
        {
            //return <0 if x < y, 0 if x = y, >0 if x > y

            //if the strings are equal return 0 now
            if (x.CompareTo(y) == 0)
                return 0;

            int x1, x2;
            int y1, y2;
            //split the strings on _
            x1 = Convert.ToInt32(x.Split('_')[0]);
            x2 = Convert.ToInt32(x.Split('_')[1]);

            y1 = Convert.ToInt32(y.Split('_')[0]);
            y2 = Convert.ToInt32(y.Split('_')[1]);

            //compare the first part
            if (x1.CompareTo(y1) == 0)
                //first parts are equal so compare the second
                return x2.CompareTo(y2);
            else
                return x1.CompareTo(y1);
        }

        #endregion
    }

Note you should obviously improve the MyComparer class, as I just assume the string will convert to integers etc.

You can split your string parse and then order by

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top