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);
Question
Please find he attached image.
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.
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