1

I need order a list in numerical order which contains strings with both numbers and words for example : "100 | Bob". Here is my code so far:

List<string> candidate = new List<string>();
candidate.Add("10 | Dave");
candidate.Add("200 | Bob");
candidate.Add("1000 | Larry");

candidate.Sort();

int i = 0;
while(i < candidate.Count)
{
    Console.WriteLine(candidate[i]);
    i++;
}

Console.ReadKey();

It currently outputs:

10 | Dave
1000 | Larry
200 | Bob

But I would like it to output:

10 | Dave
200 | Bob
1000 | Larry

any help or advice would be greatly appreciated. Thanks Jarvey.

Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
  • 1
    Try to split the string and parse the first part as an integer... that is; if the format doesn't have any exceptions. – Stefan Oct 24 '17 at 20:32
  • @Stefan Don´t rely on exceptions to parse some input. You may use `TryParse` instead. – MakePeaceGreatAgain Oct 24 '17 at 20:38
  • @HimBromBeere: with that argument you should mention why to `throw exceptions early` as well. Nevertheless, you are right, I took a shortcut there. Btw, you might want to check the marked answer ;-) – Stefan Oct 24 '17 at 21:52
  • Added just for reference: https://softwareengineering.stackexchange.com/questions/231057/exceptions-why-throw-early-why-catch-late – Stefan Oct 24 '17 at 21:53
  • @Stefan How does handling and throwing exceptions rely on sorting numbers? Can´t see your point here. – MakePeaceGreatAgain Oct 25 '17 at 06:47
  • @HimBromBeere: maybe then I was missing your point. I thought you where saying that `TryParse` is more suited then `Parse` since parse throws an exception on a incorrect format. So I my reply I tried to argue that exceptions arn't always a bad thing. But as I said, I probably misunderstood. – Stefan Oct 25 '17 at 07:41
  • @Stefan Aaah, I see. Your point was related to my comment. Missed that. Anyway if you *can* avoid an exception why not do it? Having said this using `TryParse`is IMO allwas better than using `Parse` and wait for the exception to occur. – MakePeaceGreatAgain Oct 25 '17 at 07:43

1 Answers1

0

I use LINQ for this purpose usually:

var res = candidate.OrderBy(c => int.Parse(string.Join("", c.TakeWhile(char.IsDigit))))
         .ToList();

Another way would be pad with zeroes to the same length just like below:

var res = candidate.OrderBy(c => c.PadLeft(candidate.Max(x => x.Length), '0')).ToList();
Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
  • amazing! Thanks for your help and quick reply, never came across LINQ before so this is all new to me but im going to look into it. –  Oct 24 '17 at 20:37
  • Is there a specific reason you re-opened the question? I find it´s a perfect duplicate, isn´t it? – MakePeaceGreatAgain Oct 25 '17 at 06:49
  • @HimBromBeere Hi. The duplicate question is closed as duplicate itself. So firstly I think if this question should be closed it would be better to link to original question and secondly the kind of data in the linked question is different from the kind of data in this question and finally I think the Regex solution for this problem is boring somehow IMO. – Salah Akbari Oct 25 '17 at 06:53
  • I saw thje duplicate in the duplicate. However I felt that the one I used for the vote fits the intent of the OP a bit better as it´s clearer and easier to understand what the problem is and how to solve it. In particular the p/invoke-solution of the natural-order-post is even worse than the regex-based IMO. I agree on the data-aspect however. – MakePeaceGreatAgain Oct 25 '17 at 06:59