排序包含数字和字母的字符串
本文关键字:字符串 包含 数字 排序 | 更新日期: 2023-09-27 17:49:24
我需要排序一个场景数字列表,它实际上是一个字符串列表,包含数字和字母。
这是列表
101-11
102-1
101-10
101-8
103-10
101-8A
101-9
103-4
103-4B
我做了一个比较器
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 firstSceneMatch = this.sceneRegEx.Match(sceneX.SceneNumber);
var firstSceneNumeric = Convert.ToInt32(firstSceneMatch.Groups[1].Value);
var firstSceneAlpha = firstSceneMatch.Groups[2].Value;
var secondSceneMatch = this.sceneRegEx.Match(sceneY.SceneNumber);
var secondSceneNumeric = Convert.ToInt32(secondSceneMatch.Groups[1].Value);
var secondSceneAlpha = secondSceneMatch.Groups[2].Value;
if (firstSceneNumeric < secondSceneNumeric)
{
return -1;
}
if (firstSceneNumeric > secondSceneNumeric)
{
return 1;
}
return string.CompareOrdinal(firstSceneAlpha, secondSceneAlpha);
}
}
得到以下结果
101-8
101-8A
101-9
102-1
103-4
103-4B
101-10
101-11
103-10
看起来它只对破折号之前的第一个数字和字母数字进行排序,但它不会对破折号之后的数字进行排序以获得以下所需的结果。
101-8
101-8A
101-9
101-10
101-11
102-1
103-4
103-4B
103-10
如何得到想要的结果。
您必须对字符串进行Split
并提取其中的数字以请求对这些字段进行排序。
// Assuming you have this...
List<string> list = new List<string>()
{
"101-11",
"102-1",
"101-10",
"101-8",
"103-10",
"101-8A",
"101-9",
"103-4",
"103-4B"
};
// You could do this.
var result = list.Select(x=>
{
var splits = x.Split('-');
return new
{
first = int.Parse(splits[0]),
second = int.Parse(Regex.Match(splits[1], @"'d+").Value),
item =x
};
})
.OrderBy(x=>x.first)
.ThenBy(x=>x.second)
.Select(x=>x.item)
.ToList();
Check this Demo
你很接近了。用Matches
代替Match
。
此外,更正您的Regex,因为'D
捕获非数字字符。
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;
}
}