I'm still unsure of the actual pattern we are trying to sort on but I wrote what I thought would be a solution. I saw "_" as a kind of wildcard where "abc2_" would be a subset of "abc_". But from the OPs comments "bar_" < "barxyz" breaks my understanding. Here's my code and I can modify when I gain more clarity.
static void Main(string[] args)
{
List<Element> Elements = new List<Element>();
Elements.Add(new Element("abc_"));
Elements.Add(new Element("abc2_"));
Elements.Add(new Element("aaa"));
var max = Elements.Max(e => e.Name.Length);
var result = Elements.OrderBy(e => e.Name, new CustomComparer(max));
foreach (var item in result)
Console.WriteLine(item.Name);
Console.Read();
}
class Element
{
public string Name { get; private set; }
public Element(string name)
{
this.Name = name;
}
}
class CustomComparer : Comparer<string>
{
private const string cWildCard = "_";
private const char cHeavyChar = 'Z';
public int Max { get; private set; }
public CustomComparer(int max)
{
this.Max = max;
}
public override int Compare(string a, string b)
{
string comp1 = string.Empty, comp2 = string.Empty;
int index = a.IndexOf(cWildCard);
if (index > 0)
comp1 = a.Substring(0, index).PadRight(this.Max, cHeavyChar);
index = b.IndexOf(cWildCard);
if (index > 0)
comp2 = b.Substring(0, index).PadRight(this.Max, cHeavyChar);
int result = comp1.CompareTo(comp2);
return result;
}
}
You can see I'm just weighting a word heavier from where a "_" is found. Let me know if this is on the right track.