-2

I've got an IEnumerable<string> with values like:

  • pp
  • pp.10.0
  • pp.6.0
  • pp.6.1
  • pp.8.3
  • kp.10.1
  • kp
  • kp.3.20

... etc

I'd like to organize them alphabetically, but keeping the values with double digits (in example above ones with 10.0 and 10.1) below the ones with single digits. In other words, after sorting it should look like this:

  • kp
  • kp.3.20
  • kp.10.1
  • pp
  • pp.6.0
  • pp.6.1
  • pp.8.3
  • pp.10.0

I tried a simple IEnumerable<string>.OrderBy(x => x, StringComparer.CurrentCultureIgnoreCase) but that doesn't quite work in this case.

Also bear in mind that the pp and kp parts could have dots in them as well, if you're thinking of splitting the string.

cogumel0
  • 2,430
  • 5
  • 29
  • 45
  • 1
    I am indeed thinking of splitting the string, and so should you. If those parts have dots in them as well, supply more examples. The general idea is that you want to order by some `new { key1 = ... , key2 = ..., value = s }` type that provides a compound key that *does* have a simple lexicographical ordering. – Jeroen Mostert Jul 25 '17 at 10:07
  • 1
    "Also bear in mind that the pp and kp parts could have dots in them as well, if you're thinking of splitting the string". How should it be sorted in this case? It is not clear for me. – Yeldar Kurmangaliyev Jul 25 '17 at 10:07
  • 1
    You want "natural order", such as in https://stackoverflow.com/questions/248603/natural-sort-order-in-c-sharp – Hans Kesting Jul 25 '17 at 10:09
  • You have difficulties here, because things you're trying to sort actually are more complex objects, than just a string. Consider using more strongly typed objects instead. – stop-cran Jul 25 '17 at 10:12
  • @HansKesting that works perfectly, make it an answer and I'll mark it as correct. – cogumel0 Jul 25 '17 at 10:29
  • @cogumel0 that would be a link-only answer or a copy of the original. Just upvote the answer there that helped you. But I'm glad it helped. – Hans Kesting Jul 25 '17 at 11:22

1 Answers1

4

Just create your own comparer and pass it to this overload of OrderBy: https://msdn.microsoft.com/de-de/library/bb549422(v=vs.110).aspx

For example:

IEnumerable<string>.OrderBy(x => x, new MyComparer());

Your own comparer can be a class (in the example above I named it MyComparer) that implements the Interface System.Collections.Generic.IComparer<string>. Put your compare logic into the method Compare.

class MyComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        // your logic here
    }
}

// ...

IEnumerable<string> myListOfStrings = ...;

myListOfStrings.OrderBy(x => x, new MyComparer());
Robert S.
  • 1,942
  • 16
  • 22
  • Sure, but *what* exactly would my `IComparer` look like? I mean, what logic do you use to evaluate this specific case? I know about `IComparers`, just struggling with this particular case. – cogumel0 Jul 25 '17 at 10:17
  • This depends. If the patterns are fixed (only those that you mentioned) you could use regular expressions to extract groups (the letters at the beginning, the values if present). And then you compare those groups from left to right. For values you might convert the group strings to integers and compare them to achive correct order. But there are many ways to do this I guess. Just be creative. ;) – Robert S. Jul 25 '17 at 10:21
  • My point is, show me some working code and I'll mark it as correct. As it is, your answer doesn't give me anything that works in my particular case - even if it is potentially pointing in the right direction. – cogumel0 Jul 25 '17 at 10:33
  • I don't want to do your homework. And your question wasn't quite clear. Next time please be more precise. E.g. state that the sort algorithm is your problem and not how to sort an `IEnumerable` with custom logic. – Robert S. Jul 25 '17 at 11:47