Reputation: 117
How to sort this?
I have List of string with values like this
11-03-2013
11-03-2013 -Count=2
11-03-2013 -count=1
11-04-2013 -Count=1
11-04-2013 -Count=2
11-04-2013
Output should be, The one without the count should be on the last and the top most should be 1 followed by 1 and dates should be ordered by ascending.
11-03-2013 -Count=2
11-03-2013 -count=1
11-03-2013
11-04-2013 -Count=2
11-04-2013 -Count=1
11-04-2013
I tried this code but this is sorting this by descending
var edates= edates.OrderBy(e => e.Replace("-count=1", string.Empty).Replace("-count=2", string.Empty)).ToList();
I know that a simple class with properties can do the trick but doing that so would need to change other methods which would require a lot of work.
Regards
Upvotes: 3
Views: 1084
Reputation: 15865
Here is @Guru Stron's solution in code
private static void sortList()
{
var dates = getDates();
var sorted = dates.OrderBy(f1).ThenByDescending(f2);
}
private static DateTime f1(string parse)
{
return DateTime.Parse(parse.Substring(0, 10));
}
private static int f2(string parse)
{
int sort;
if (parse.Length > 10) int.TryParse(parse.Substring(18), out sort);
else sort = 0;
return sort;
}
Upvotes: 2
Reputation: 141895
it is because you compare strings not dates. Create two functions: first substrings date part and parses it and second substrings the count part and returns parsed count(or 0 if length < 11) and then yourList.OrderBy(s=> f1(s)).ThenByDescending(s=> f2(s))
Upvotes: 3
Reputation: 61875
The following should order as desired across different years and counts >= 10.
This won't be the "fastest" method (and it will most certainly not work with L2S/EF LINQ providers), but it should sort the given format correctly and fail-fast on invalid values. I would likely write the code like this (or use an IComparer
with an equivalent setup) - mainly because it "reads simple" to me.
DateTime OrderableItem (string e) {
var date = e.Substring(0, 10);
return DateTime.ParseExact(date, "MM-dd-yyyy", CultureInfo.InvariantCulture)
}
int OrderableCount (string e) {
var m = Regex.Match(e, @"-count=(\d+)$", RegexOptions.IgnoreCase);
return m.Success
? int.Parse(m.Groups[1].Value)
: 0;
}
var res = seq.OrderBy(OrderableDate)
.ThenBy(OrderableCount);
I much prefer to take data, instead of excluding data.
Upvotes: 0
Reputation: 180917
You first need to order by the date, then by the rest of the string, descending;
edates =
edates.OrderBy(x =>
DateTime.ParseExact(x.Substring(0, 10), "MM-dd-yyyy",
CultureInfo.InvariantCulture))
.ThenByDescending(x => x.Substring(10))
.ToList();
Upvotes: 1
Reputation: 96477
You ought to use a real class to simplify things and have a proper representation. That said, you can use the LINQ query syntax and take advantage of the let
clause to store the result of splitting the text on a space and the equal symbol. If the split result has more than one element we can assume the count exists. Next, we order by the date (after parsing it) and then by parsing the count (descending).
Try this approach out:
string[] inputs =
{
"11-03-2013",
"11-03-2013 -Count=2",
"11-03-2013 -Count=1",
"11-04-2013 -Count=1",
"11-04-2013 -Count=2",
"11-04-2013"
};
var query = from input in inputs
let split = input.Split(' ', '=')
let count = split.Length > 1 ? int.Parse(split[2]) : 0
orderby DateTime.Parse(split[0]), count descending
select input;
foreach (var item in query)
{
Console.WriteLine(item);
}
Upvotes: 0