假设我有一个多部分问题列表,每个问题都有一个问题编号,如1
,1a
,1b
,2
,2a
和等等。我想使用linq-to-entities从数据库中获取问题列表,但是按QuestionNumber排序。问题是,它不是使用正确的顺序,而是使用像
1
11
11a
11b
1a
1b
2
22
到目前为止我所拥有的是自定义比较器:
public class QuestionCompare : IComparer<Question>
{
public int Compare(Question x, Question y)
{
string a = x.QuestionNumber;
string b = y.QuestionNumber;
if (a == b)
{
return 0;
}
int aInt;
bool aBool = Int32.TryParse(new String(a.Where(Char.IsDigit).ToArray()), out aInt);
int bInt;
bool bBool = Int32.TryParse(new String(b.Where(Char.IsDigit).ToArray()), out bInt);
if (aBool)
{
if (bBool)
{
if (aInt > bInt)
{
return 1;
}
else if (aInt < bInt)
{
return -1;
}
else
{
string aLetter = new String(a.Where(Char.IsLetter).ToArray());
string bLetter = new String(a.Where(Char.IsLetter).ToArray());
return StringComparer.CurrentCulture.Compare(aLetter, bLetter);
}
}
else
{
return 1;
}
}
else
{
if (bBool)
{
return -1;
}
else
{
return StringComparer.CurrentCulture.Compare(a, b);
}
}
return 0;
}
}
您可以致电Array.Sort(questionArray,new QuestionCompare())
以正确的顺序提问。
但是,我觉得这是一个常见的,定义明确的顺序,所以我想知道是否有更好的实现,甚至是内置于.Net框架的内容。
答案 0 :(得分:1)
这个比较器工作正常,而且相当短。
public class QuestionCompare : IComparer<Question>
{
public int Compare(Question x, Question y)
{
string a = x.QuestionNumber;
string b = y.QuestionNumber;
var aDigits = new string(a.TakeWhile(c => char.IsDigit(c)).ToArray());
var bDigits = new string(b.TakeWhile(c => char.IsDigit(c)).ToArray());
int aInt = String.IsNullOrEmpty(aDigits) ? 0 : int.Parse(aDigits);
int bInt = String.IsNullOrEmpty(bDigits) ? 0 : int.Parse(bDigits);
return aInt != bInt ? aInt.CompareTo(bInt) : a.CompareTo(b);
}
}