How to perform sorting on the list of mm-yyyy strings along with mixed words using custom comparer with memory-optimized way.
List<string> result = new List<string>();
result.Add("04-2020");
result.Add("03-2021");
result.Add("Nan");
CodePudding user response:
You can achieve this using Linq and the use of DateTime.TryParseExact
var orderedList = result.OrderByDescending(x =>
{
DateTime dt;
DateTime.TryParseExact(x, "MM-yyyy", CultureInfo.InvariantCulture,
DateTimeStyles.None, out dt);
return dt;
}).ToList();
CodePudding user response:
You could use Linq as Ran suggested in his answer, and it will work nicely.
However there is another alternative that will probably be more memory-optimized (though admittedly I didn't check):
The List<T> type has a built in Sort method that have several overloads, one of them takes in a Comparison<T> delegate.
Using it will probably be better memory-optimized than using Linq, because you wouldn't need to allocate a new List<T>.
Here's one way you can use it (of course, you can use a named method instead of a lambda expression):
result.Sort((a, b) => {
var dateA = DateTime.TryParseExact(a, "MM-yyyy", CultureInfo.InvariantCulture,DateTimeStyles.None, out var dtA) ? dtA : DateTime.MinValue; // change to MaxValue if needed
var dateB = DateTime.TryParseExact(b, "MM-yyyy", CultureInfo.InvariantCulture,DateTimeStyles.None, out var dtB) ? dtB : DateTime.MinValue; // change to MaxValue if needed
return dateB.CompareTo(dateA); // Assending order
return dateA.CompareTo(dateB); // Descending order
});
CodePudding user response:
If you also want to sort the "non-dates", then you cannot ignore those (building on previous answers):
List<string> result = new List<string>();
result.Add("04-2020");
result.Add("03-2021");
result.Add("04-2021");
result.Add("2-2021");
result.Add("Nan");
result.Add("Aan");
result.Add("Xan");
var sorted = result.OrderBy(s =>
{
DateTime dt;
if (DateTime.TryParseExact(s, "M-yyyy",
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.None, out dt))
return (dt, "");
return (DateTime.MaxValue, s);
}).ToList();
This builds a tuple of (DateTime, string), with the date filled in when it did parse, otherwise only the string is filled (with the original string value).
Result:
04-2020
2-2021
03-2021
04-2021
Aan
Nan
Xan
