我有一个List<String>
l_lstTemp,其中包含
"A1"
"A1_1"
"A1_2"
"1A"
"B2_1"
"B1_2"
"B1_1_2"
"A10"
"B11"
"A"
"Z"
我需要根据字符和数值对项目进行排序。
所以排序后的列表就像
"1A"
"A"
"A1"
"A1_1"
"A1_2"
"A10"
"B1_1_2"
"B1_2"
"B2_1"
"B11"
"Z"
这是我的代码:
l_lstTemp.Sort(delegate(String One, String Two)
{
Match l_mOne = Regex.Match(One, @"(\D*)(\d*)");
Match l_mTwo = Regex.Match(Two, @"(\D*)(\d*)");
int Result;
if (l_mOne.Success || l_mTwo.Success)
{
String l_strX, l_strY;
l_strX = l_mOne.Groups[1].Value;
l_strY = l_mTwo.Groups[1].Value;
Result = l_strX.CompareTo(l_strY);
if (Result != 0)
return Result;
l_strX = l_mOne.Groups[2].Value;
l_strY = l_mTwo.Groups[2].Value;
if (l_strX == String.Empty || l_strY == String.Empty)
{
Result = l_strX.CompareTo(l_strY);
if (Result != 0)
return Result;
}
else
{
long X = long.Parse(l_strX);
long Y = long.Parse(l_strY);
Result = X.CompareTo(Y);
if (Result != 0)
return Result;
}
}
return 0 ;
}
);
但它没有正常工作(排序)。
如何修改代码以正确排序列表?
请给我一个方法来做这件事。
提前致谢。
答案 0 :(得分:3)
我对您的代码进行了一些修改。问题是当Group 1
和Group 2
都相等时,仍然需要检查剩下的内容。
重要提示:我在您的代码中进行了修改,因此这可能有点棘手。我真的建议你重构代码,因为你知道它有效:
l.Sort(delegate(String One, String Two)
{
while (One != "" && Two != "")
{
if (One == Two)
return 0;
//Add one more group to capture what remains of the expression
Match l_mOne = Regex.Match(One, @"_*(\D*)(\d*)(.*)$");
Match l_mTwo = Regex.Match(Two, @"_*(\D*)(\d*)(.*)$");
int Result;
if (l_mOne.Success || l_mTwo.Success)
{
String l_strX, l_strY;
l_strX = l_mOne.Groups[1].Value;
l_strY = l_mTwo.Groups[1].Value;
Result = l_strX.CompareTo(l_strY);
if (Result != 0)
return Result;
l_strX = l_mOne.Groups[2].Value;
l_strY = l_mTwo.Groups[2].Value;
if (l_strX == String.Empty || l_strY == String.Empty)
{
Result = l_strX.CompareTo(l_strY);
if (Result != 0)
return Result;
}
else
{
long X = long.Parse(l_strX);
long Y = long.Parse(l_strY);
Result = X.CompareTo(Y);
if (Result != 0)
return Result;
One = l_mOne.Groups[3].Value; //Store in 'One' the remaining part of the regex
Two = l_mTwo.Groups[3].Value; //The same in Two
continue; //The result will be the result of the comparison of those two new values.
}
}
}
return One.CompareTo(Two);
});
修改强>
我还在字符串开头添加了_*
到删除所有_
个字符。我假设这些字符串在数字后面只包含_
,而不是B1B
或B1$
。
这里的事情是你没有真正解释应该如何进行比较,我不得不从你的原始数据和排序数据中假设这些东西,否则如果要排序{{1}会发生什么和A1A
?它应该返回什么?
答案 1 :(得分:1)
这是我如何实现这样的比较器。更容易关注恕我直言。
var re = new Regex(@"^(\d+)?([A-Z]+)(\d+)?(?:_(\d+)(?:_(\d+))?)?$");
Func<Group, int, int> intOrDefault = (g, d) => g.Success ? Convert.ToInt32(g.Value) : d;
list.Sort((x, y) =>
{
var xm = re.Match(x);
var ym = re.Match(y);
int cmp;
// compare the first group
// compare the leading numbers (if any)
cmp = intOrDefault(xm.Groups[1], int.MaxValue).CompareTo(intOrDefault(ym.Groups[1], int.MaxValue));
if (cmp != 0)
return cmp;
// compare letters
cmp = xm.Groups[2].Value.CompareTo(ym.Groups[2].Value);
if (cmp != 0)
return cmp;
// compare the trailing numbers (if any)
cmp = intOrDefault(xm.Groups[3], 0).CompareTo(intOrDefault(ym.Groups[3], 0));
if (cmp != 0)
return cmp;
// compare the next group
cmp = intOrDefault(xm.Groups[4], 0).CompareTo(intOrDefault(ym.Groups[4], 0));
if (cmp != 0)
return cmp;
// compare the last group
cmp = intOrDefault(xm.Groups[5], 0).CompareTo(intOrDefault(ym.Groups[5], 0));
return cmp;
});
答案 2 :(得分:-3)
对于此示例,只需调用sort l_lstTemp.Sort()
即可获得您要查找的结果