Reputation: 1263
I have an array of strings like the following:
"access"
"Addition"
"account"
"base"
"Brick"
"zammer"
"Zilon"
I want them to sort them witht the following rules"
Thus, the output should be:
"Addition"
"access"
"account"
"Brick"
"base"
"Zilon"
"zammer"
The language I am using is C# and .Net 4.0.
Upvotes: 1
Views: 234
Reputation: 14856
If you want to go beyond the first character, I should implement a comparer:
class MyComparer : IComparer<string>
{
public int Compare(string x, string y)
{
if ((x == null) && (y == null))
{
return 0;
}
if (x == null)
{
return 1;
}
if (y == null)
{
return -1;
}
var l = Math.Min(x.Length, y.Length);
for (var i = 0; i < l; i++)
{
var c = x[i];
var d = y[i];
if (c != d)
{
if (char.ToLowerInvariant(c) == char.ToLowerInvariant(d))
{
return StringComparer.Ordinal.Compare(new string(c, 1), new string(d, 1));
}
else
{
return StringComparer.OrdinalIgnoreCase.Compare(new string(c, 1), new string(d, 1));
}
}
}
return x.Length == y.Length ? 0 : x.Length > y.Length ? 1 : -1;
}
}
And then use it:
var myComparer = new MyComparer();
source.OrderBy(s => s, myComparer);
Upvotes: 0
Reputation: 1
Below solution works for more than one Caps.
static void Main(string[] args)
{
var names = new List<String>() {
"access",
"Addition",
"ADDition",
"ADdition",
"account",
"base",
"Brick",
"zammer",
"Zilon"
};
names.Sort((one, two) =>
{
int result = 0;
var oneArray = one.ToCharArray();
var twoArray = two.ToCharArray();
var minLength = Math.Min(oneArray.Length, twoArray.Length) - 1;
var i = 0;
while (i < minLength)
{
//Diff Letter
if (Char.ToUpper(one[i]) != Char.ToUpper(two[i]))
{
result = Char.ToUpper(one[i]) - Char.ToUpper(two[i]);
break;
}
// Same Letter, same case
if (oneArray[i] == twoArray[i])
{
i++;
continue;
}
// Same Letter, diff case
result = one[i] - two[i];
break;
}
return result;
});
foreach (string s in names)
Console.WriteLine(s);
Console.WriteLine("done");
Upvotes: 0
Reputation: 125660
Proper set of OrderBy
/ThenBy
calls will do the trick.
a
s and A
s first, then b
s and B
s, etc.IsLower(firstCharacter)
, which will get the uppercased items for each letter first.var sorted = source.OrderBy(s => char.ToLower(s[0]))
.ThenBy(s => char.IsLower(s[0]))
.ThenBy(s => s)
.ToList();
Upvotes: 7
Reputation: 28413
Try like this
List<string> list = new List<string>();
list.Add("access");
list.Add("Addition");
list.Add("account");
list.Add("base")
list.Add("Brick")
list.Add("zammer")
list.Add("Zilon")
list = list.Where(r => char.IsLower(r[0])).OrderBy(r => r)
.Concat(list.Where(r => char.IsUpper(r[0])).OrderBy(r => r)).ToList();
for (int i = 0; i < list.Count; i++)
Console.WriteLine(list[i]);
Upvotes: 0