我需要能够对包含数字字符串属性的客户集合进行排序。
如何按数字顺序按代码对下面的集合进行排序。再次Code是一个字符串。
class Program
{
static void Main(string[] args)
{
SortableObservableCollection<Customer> customerList = new SortableObservableCollection<Customer>();
customerList.Add(new Customer() {Name = "Jo", Code = "1"});
customerList.Add(new Customer() { Name = "Jo", Code = "10" });
customerList.Add(new Customer() { Name = "Jo", Code = "11" });
customerList.Add(new Customer() { Name = "Jo", Code = "9" });
customerList.Add(new Customer() { Name = "Jo", Code = "7" });
customerList.Add(new Customer() { Name = "Jo", Code = "12" });
customerList.Add(new Customer() { Name = "Jo", Code = "13" });
customerList.Add(new Customer() { Name = "Jo", Code = "2" });
customerList.Add(new Customer() { Name = "Jo", Code = "5" });
customerList.Add(new Customer() { Name = "Jo", Code = "7" });
//Order them by Code How
}
}
public class Customer
{
public string Name { get; set; }
public string Code { get; set; }
}
感谢您的任何建议
答案 0 :(得分:17)
选项1:实施IComparer<Customer>
并在
选项2:使用LINQ做同样的事情:
customerList = customerList.OrderBy(c => int.Parse(c.Code)).ToList();
选项3:更改Customer类,以便将数值存储为数字类型:)
编辑:如上所述,如果您向客户提供非数字代码,则会引发异常。
另外,我正在呼叫ToList()
因为我认为你仍然需要它作为一个列表。如果您只需按顺序迭代结果,请使用:
IEnumerable<Customer> ordered = customerList.OrderBy(c => int.Parse(c.Code));
请注意,如果迭代两次,它将执行所有解析和排序两次。
答案 1 :(得分:7)
如果键总是只是数字,那些数字总是可以转换为int,那么它非常简单。只需将它们转换为整数。
var sorted = from customer in customerList orderby Int32.ParseInt(customer.Code) select customer;
如果它们中的任何一个不是整数,那么这将会崩溃。
另一种方法是用前导零填充字符串:
var sorted = from customer in customerList orderby PadToTenDigits(customer.Code) select customer;
其中PadToTenDigits是一个留作练习的方法,将“1”变为“0000000001”,将“1000”变为“0000001000”,依此类推。
如果你必须对复杂的代码进行真正的“数字”排序,例如,代码“A300-B”在“A1000-XYZ”之前进行排序,那么你手上就会遇到更难的问题。诀窍是将代码分解为“部分”并对每个部分进行稳定的排序。基本上,基数排序。
答案 2 :(得分:3)
您对“准则”(a)数字和(b)存在有多大信心?
var sortedList = customerList.OrderBy(c => int.Parse(c.Code));
如果您有疑问,请尝试另一种方法
Func<string, bool> isInteger = s => { int temp; return int.TryParse(s, out temp); };
var query = customerList.OrderBy(c => isInteger(c.Code) ? int.Parse(c.Code) : int.MaxValue);
或者减少attemtps的数量来解析值并将逻辑保留在一个委托中:
Func<string, int> intParser = input =>
{
int result;
if (!int.TryParse(input, out result))
return int.MaxValue;
return result;
};
var query = customerList.OrderBy(c => intParser(c.Code)); // .ToList() if you wish
注意:我正在使用int.MaxValue将非整数输入移动到行的后面。您可以根据您希望这些对象的位置选择其他值。
答案 3 :(得分:-2)
尝试LINQ to Objects:
var result = from c in customerList
orderby Int.Parse(c.Code)
select c;