-2

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.

pravprab
  • 2,301
  • 3
  • 26
  • 43
user1687824
  • 807
  • 2
  • 10
  • 24

5 Answers5

2

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

Lucky Lefty
  • 347
  • 1
  • 8
2

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.

Baldrick
  • 11,712
  • 2
  • 31
  • 35
2

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);
Oscar Bralo
  • 1,912
  • 13
  • 12
  • This might work in this sample, but your final object is a Dictionary which is not ordered. If it works, it is just the luck of the implementation. – Baldrick Feb 18 '14 at 13:43
  • Here is a good explanation of what I mean from the master! Http://stackoverflow.com/questions/6384710/why-is-a-dictionary-not-ordered – Baldrick Feb 18 '14 at 13:45
  • Thanks for your comments Baldrick! ;) They are useful! – Oscar Bralo Feb 18 '14 at 13:58
1

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.

cjb110
  • 1,310
  • 14
  • 30
0

You can split your string parse and then order by

ale
  • 10,012
  • 5
  • 40
  • 49