I have a List<string>
, where the entries are locations, like "010101", "010102", "010201", ..., with following meaning:
Normal sorting reveals a list like the following:
010101
010102
010103
010201
010202
020101
020102
020201
020202
020203
020204
...
I would like a custom sorting, where:
on floor "01", the sorting is done in a normal way:
010101
010102
010103
010201
010202
on floor "02", the sorting is done in a reversed way for the lane, but not for the entry in lane, so something like:
...
020201
020202
020203
020204
020101
020102
Here on the site, I've found the IEnumerable
as a solution, but this only works for List<T>
where T
is a new class. This is not relevant here, as I'm dealing with "simple" strings.
I've also found the Enumerable
as a solution, but this also doesn't work, because the list of possible strings is far too large (not enumerable) and I'd prefer a flexible solution.
Does anybody have an idea?
Thanks in advance
There are multiple ways to achieve the desired behavior, e.g. using a Comparison<string>
:
var input = new List<string>() { "010101", "010102", "010103", "010201", "010202", "020101", "020102", "020201", "020202", "020203", "020204" };
Comparison<string> comparison = (s1, s2) =>
{
if (s1 == null) throw new ArgumentNullException(nameof(s1));
if (s2 == null) throw new ArgumentNullException(nameof(s2));
if (s1.Length != 6 || s2.Length != 6) throw new ArgumentOutOfRangeException();
// Compare floor (first 2 digits)
var floor1 = s1.Substring(0, 2);
var floor2 = s2.Substring(0, 2);
var result = floor1.CompareTo(floor2);
if (result != 0) return result;
// Compare lane (middle 2 digits)
var lane1 = s1.Substring(2, 2);
var lane2 = s2.Substring(2, 2);
// Special case: in floor 02, reverse order of lanes
result = floor1 == "02"
? lane2.CompareTo(lane1)
: lane1.CompareTo(lane2);
if (result != 0) return result;
// Compare entry (last 2 digits)
return s1.Substring(4, 2).CompareTo(s2.Substring(4, 2));
};
// Sort the list using the comparison defined before
input.Sort(comparison);