我的数组中的每个项目/字符串以两个字母开头,后跟两个或三个数字,然后有时后跟另一个字母。
示例,RS01 RS10 RS32A RS102 RS80 RS05A RS105A RS105B
我尝试使用默认的Array.Sort对此进行排序,但是它回来了......
RS01
RS05A
RS10
RS102
RS105A
RS105B
RS32A
RS80
但我需要这样......
RS01
RS05A
RS10
RS32A
RS80
RS102
RS105A
RS105B
任何想法?
答案 0 :(得分:5)
以下是使用自定义比较委托和正则表达式进行排序:
string[] array = { "RS01", "RS10", "RS32A", "RS102",
"RS80", "RS05A", "RS105A", "RS105B" };
Array.Sort(array, (s1, s2) =>
{
Regex regex = new Regex(@"([a-zA-Z]+)(\d+)([a-zA-Z]*)");
var match1 = regex.Match(s1);
var match2 = regex.Match(s2);
// prefix
int result = match1.Groups[1].Value.CompareTo(match2.Groups[1].Value);
if (result != 0)
return result;
// number
result = Int32.Parse(match1.Groups[2].Value)
.CompareTo(Int32.Parse(match2.Groups[2].Value));
if (result != 0)
return result;
// suffix
return match1.Groups[3].Value.CompareTo(match2.Groups[3].Value);
});
UPDATE(很少重构,并将所有内容移动到单独的比较器类)。用法:
Array.Sort(array, new RSComparer());
比较自己:
public class RSComparer : IComparer<string>
{
private Dictionary<string, RS> entries = new Dictionary<string, RS>();
public int Compare(string x, string y)
{
if (!entries.ContainsKey(x))
entries.Add(x, new RS(x));
if (!entries.ContainsKey(y))
entries.Add(y, new RS(y));
return entries[x].CompareTo(entries[y]);
}
private class RS : IComparable
{
public RS(string value)
{
Regex regex = new Regex(@"([A-Z]+)(\d+)([A-Z]*)");
var match = regex.Match(value);
Prefix = match.Groups[1].Value;
Number = Int32.Parse(match.Groups[2].Value);
Suffix = match.Groups[3].Value;
}
public string Prefix { get; private set; }
public int Number { get; private set; }
public string Suffix { get; private set; }
public int CompareTo(object obj)
{
RS rs = (RS)obj;
int result = Prefix.CompareTo(rs.Prefix);
if (result != 0)
return result;
result = Number.CompareTo(rs.Number);
if (result != null)
return result;
return Suffix.CompareTo(rs.Suffix);
}
}
}
答案 1 :(得分:2)
您可以使用此linq查询:
var strings = new[] {
"RS01","RS05A","RS10","RS102","RS105A","RS105B","RS32A","RS80"
};
strings = strings.Select(str => new
{
str,
num = int.Parse(String.Concat(str.Skip(2).TakeWhile(Char.IsDigit))),
version = String.Concat(str.Skip(2).SkipWhile(Char.IsDigit))
})
.OrderBy(x => x.num).ThenBy(x => x.version)
.Select(x => x.str)
.ToArray();
结果:
RS01
RS05A
RS10
RS32A
RS80
RS102
RS105A
RS105B
答案 2 :(得分:0)
您需要编写一个实现IComparer<string>
的自定义比较器类;将字符串分解为组件非常简单。当你致电Array.Sort
时,给它一个比较器的实例,你就会得到你想要的结果。