I want to sort the list: (2012-09, 2012-10,2012-11,2012-12,2013-01, 2013-02,2013-03,2013-04,2013-05, 2013-06,2013-07,2013-08)
into a new list (2013-01, 2013-02, 2013-03, 2013-04 etc etc, 2012-09, 2012-10)
how can I do this in C#?
Try this:
var sorted = notSorted.OrderByDescending(x => x.Year).ThenBy(x => x.Month).ToList();
It will sort your DateTimes (I assume that they are DateTimes), first on Year descending then on Month ascending, so it will produce that list you are expecting
If they are not DateTimes you can parse them using DateTime.Parse or DateTime.ParseExact
var sorted = list.ToList(); sorted.Sort(); will be enough I thinklist.ToList just creates a new list with the same content and order as before whereas sorted.Sort() will sort the original list but lowest years first.If your list does not contain datetime objects but insteads strings, you could order them the following way:
var unsortedArray = new string[] { "2012 - 09", "2012 - 10", "2012 - 11", "2012 - 12", "2013 - 01", "2013 - 02", "2013 - 03", "2013 - 04", "2013 - 05", "2013 - 06", "2013 - 07", "2013 - 08" };
var sortArray = unsortedArray.Select(x =>
{
var split = x.Split(new string[] { " - " }, StringSplitOptions.None);
return new { Original = x, Year = split[0], Month = split[1] };
})
.OrderByDescending(x => x.Year)
.ThenBy(x => x.Month)
.Select(x => x.Original)
.ToArray();
" - ", there is always a month at all, so no invalid data. The best approach is to TryParse the strings to DateTime, use wudzik's order..PadLeft(2,'0'). This is just an option to sort the list.If list is a List<string> you can use following code
lst = lst.OrderByDescending(a => a.Substring(0, 4)).OrderBy(a => a.Substring(5, 2)).ToList();
- between year and month. Also, this does order lexicographically which means "9" is higher than "10", in case that the months do not necessarily have two digits. It is also not safe if the input might contain invalid data.You could create your own implementation of IComparer to deal with this which may allow more maintainability should your data structure change.
Here's a crude example to work with your provided example.
public class MonthYearStringComparer : IComparer<string>
{
public int Compare(string x, string y)
{
if (x == null && y == null) return 0;
if (x == null) return -1;
if (y == null) return 1;
int[] xArray = x.Split('-').Select(xVal => int.Parse(xVal)).ToArray();
int[] yArray = y.Split('-').Select(yVal => int.Parse(yVal)).ToArray();
// x year is earlier
if (xArray[0] < yArray[0]) return 1;
// y year is earlier
if (xArray[0] > yArray[0]) return -1;
// years are same
// x month is earlier
if (xArray[1] < yArray[1]) return 1;
// y month is earlier
if (xArray[1] > yArray[1]) return -1;
// same
return 0;
}
http://msdn.microsoft.com/en-us/library/234b841s.aspx
Then all you have to is instantiate your sorter and use it as a parameter in the sort method.
MonthYearStringComparer comparer = new MonthYearStringComparer();
myListOfYearAndMonthStrings.Sort(comparer);
List<DateTime>orList<string>?