要用linq实现类似以下的排序
1, 5, 500 , LT, RT, 400 -> LINQ -> 1, 5, 400, 500, LT, RT
本来想自己想个方法,不过在stackoverflow上找到下面这个
int results = 0;
// Grabs all voltages
var voltage = ActiveRecordLinq.AsQueryable<Equipment>()
.OrderBy(x => x.Voltage)
.Select(x => x.Voltage)
.Distinct()
.ToList();
// Order by numeric
var numberVoltage = voltage
.Where( x => int.TryParse(x, out results))
.OrderBy( x => Convert.ToInt32(x));
// Then by alpha
var letterVoltage = voltage
.Where(x=> !String.IsNullOrEmpty(x))
.Where(x => !int.TryParse(x, out results))
.OrderBy(x => x);
return numberVoltage.Union(letterVoltage)
不过更牛拜的人说酱紫更好
return ActiveRecordLinq.AsQueryable<Equipment>()
.Select(x => x.Voltage)
.Distinct()
.AsEnumerable() // Do the rest in-process
.Where(x => !string.IsNullOrEmpty(x))
.OrderBy(x => x, new AlphaNumericComparer())
.ToList();
AlphaNumericComparer是对IComparer<string>接口的实现,类似于下面
public int Compare(string first, string second)
{
// For simplicity, let's assume neither is null :)
int firstNumber, secondNumber;
bool firstIsNumber = int.TryParse(first, out firstNumber);
bool secondIsNumber = int.TryParse(second, out secondNumber);
if (firstIsNumber)
{
// If they're both numbers, compare them; otherwise first comes first
return secondIsNumber ? firstNumber.CompareTo(secondNumber) : -1;
}
// If second is a number, that should come first; otherwise compare
// as strings
return secondIsNumber ? 1 : first.CompareTo(second);
}
or 更装逼的写法
public int Compare(string first, string second)
{
// For simplicity, let's assume neither is null :)
int firstNumber, secondNumber;
bool firstIsNumber = int.TryParse(first, out firstNumber);
bool secondIsNumber = int.TryParse(first, out secondNumber);
return firstIsNumber
? secondIsNumber ? firstNumber.CompareTo(secondNumber) : -1;
: secondIsNumber ? 1 : first.CompareTo(second);
}