我有一个ListCollectionView,它包含一组场景对象,我需要按场景Number(Scene.SceneNumber)对它进行排序,这是一个包含数字和字母的字符串,我需要按照特定的顺序对其进行排序。首先是数字,然后是字母,首先是小写字母,然后是大写字母。
列表需要如下所示:
1
1pt1
1pt2
1A
1Apt1
2
2pt1
2Apt1
3
...
这是我到目前为止所做的:
public class SceneComparer : IComparer
{
private readonly Regex sceneRegEx = new Regex(@"(\d+)(\w+)?", RegexOptions.Compiled);
public int Compare(object x, object y)
{
Scene sceneX = x as Scene;
Scene sceneY = y as Scene;
var firstSceneMatches = this.sceneRegEx.Matches(sceneX.SceneNumber);
var secondSceneMatches = this.sceneRegEx.Matches(sceneY.SceneNumber);
var matchesCount = Math.Min(firstSceneMatches.Count, secondSceneMatches.Count);
for (var i = 0; i < matchesCount; i++)
{
var firstSceneMatch = firstSceneMatches[i];
var secondSceneMatch = secondSceneMatches[i];
var firstSceneNumeric = Convert.ToInt32(firstSceneMatch.Groups[1].Value);
var secondSceneNumeric = Convert.ToInt32(secondSceneMatch.Groups[1].Value);
if (firstSceneNumeric != secondSceneNumeric)
{
return firstSceneNumeric - secondSceneNumeric;
}
var firstSceneAlpha = firstSceneMatch.Groups[2].Value;
var secondSceneAlpha = secondSceneMatch.Groups[2].Value;
if (firstSceneAlpha != secondSceneAlpha)
{
return string.CompareOrdinal(firstSceneAlpha, secondSceneAlpha);
}
}
return firstSceneMatches.Count - secondSceneMatches.Count;
}
}
这导致以下列表
1
1A
1Apt1
1pt1
1pt2
2
2Apt1
2pt1
...
但我需要大写字母前面的小写字母。我该怎么做?
答案 0 :(得分:-1)
//Usage:
var sortedStrs = strings.OrderBy(s => s, new CollectionComparer<char>(CompareChar)).ToList();
private static int CompareChar(char c1, char c2)
{
if (char.IsNumber(c1) || char.IsNumber(c2))
{
return c1 - c2;
}
var s1 = c1.ToString();
var s2 = c2.ToString();
var isLowerCaseS1 = s1 == s1.ToLower();
var isLowerCaseS2 = s2 == s2.ToLower();
if (isLowerCaseS1 && isLowerCaseS2 || !isLowerCaseS1 && !isLowerCaseS2)
{
return c1.CompareTo(c2);
}
return isLowerCaseS1 ? -1 : 1;
}
public class CollectionComparer<T> : IComparer<IEnumerable<T>>
{
private readonly Func<T, T, int> _comparisonFunc;
public CollectionComparer(Func<T, T, int> comparisonFunc)
{
_comparisonFunc = comparisonFunc;
}
public int Compare(IEnumerable<T> c1, IEnumerable<T> c2)
{
//Ensure.Argument.NotNull(c1);
//Ensure.Argument.NotNull(c2);
var collection2 = c2?.ToList() ?? new List<T>();
var collection1 = c1?.ToList() ?? new List<T>();
var result = collection1.Select(
(c, ind) => collection2.Count() > ind ? _comparisonFunc(c, collection2.ElementAt(ind)) : 1)
.FirstOrDefault(e => e != 0);
return result != 0 ? result : (collection2.Count > collection1.Count() ? -1 : 0);
}
}