namespace SortableLists
{
using System;
using System.Collections.Generic;
public class Program
{
private static void Main() {
var list = new List<ListItem>
{
new ListItem {AdmissionCode = "801r", Name = "Rajesh Koothrappali", RollNumber = 54},
new ListItem {AdmissionCode = "892k", Name = "Leonard Leakey Hofstadter", RollNumber = 34},
new ListItem {AdmissionCode = "1203a", Name = "Sheldon Lee Cooper", RollNumber = 46},
new ListItem {AdmissionCode = "802x", Name = "Howard Wolowitz", RollNumber = 98}
};
list.ForEach(x => Console.WriteLine(x.RollNumber + ","+x.Name + "," + x.AdmissionCode));
Console.Write("\n");
list.Sort();
list.ForEach(x => Console.WriteLine(x.RollNumber + "," + x.Name + "," + x.AdmissionCode));
Console.ReadKey();
}
}
public class ListItem : IComparable<ListItem>
{
public int RollNumber { get; set; }
public string Name { get; set; }
public string AdmissionCode { get; set; }
#region Implementation of IComparable<in ListItem>
public int CompareTo(ListItem other) {
return AdmissionCode.CompareTo(other.AdmissionCode);
}
#endregion
}
}
我不知道这是什么样的排序这是排序代码1203谢尔顿博士在排序后出现在列表顶部的地方???我期待801,802,803和1203 ...有人可以解释一下吗?
答案 0 :(得分:4)
您要比较的数字不会被视为数字而是字符串!对于字符串,字母“1”出现在“8”之前,因此较大的数字首先出现,因为当被视为文本时,顺序是不同的。
如果您希望将此字段视为一个字段,我建议您将此字段转换为int
。
编辑:对于您编辑过的问题(字段现在还包含字母),您需要编写自定义比较逻辑,以便按照您想要的顺序进行比较。
例如,我想你希望逻辑是这样的:
在您的CompareTo方法中实现此逻辑(或您真正想要的任何逻辑),您将获得所需的订单。
这种逻辑的代码可能是这样的:
public class ListItem : IComparable<ListItem>
{
public int RollNumber { get; set; }
public string Name { get; set; }
public string AdmissionCode { get; set; }
private static readonly char[] Numbers = new[]
{
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9'
};
#region Implementation of IComparable<in ListItem>
public int CompareTo(ListItem other)
{
// Assumes AdmissionCode is in ####ABC format,
// with at least one number and any amount of letters.
string myNumberPart, myRemainingPart;
string otherNumberPart, otherRemainingPart;
SplitAdmissionCode(AdmissionCode, out myNumberPart, out myRemainingPart);
SplitAdmissionCode(other.AdmissionCode, out otherNumberPart, out otherRemainingPart);
int myNumber = int.Parse(myNumberPart);
int otherNumber = int.Parse(otherNumberPart);
int result = myNumber.CompareTo(otherNumber);
// Numbers are different.
if (result != 0)
return result;
// Numbers are same. Use text compare for the remaining part.
return myRemainingPart.CompareTo(otherRemainingPart);
}
private void SplitAdmissionCode(string code, out string numbersPart, out string remainingPart)
{
int lastNumberIndex = code.LastIndexOfAny(Numbers);
numbersPart = code.Substring(0, lastNumberIndex + 1);
if (lastNumberIndex == code.Length - 1)
remainingPart = "";
else
remainingPart = code.Substring(lastNumberIndex + 1);
}
#endregion
}
答案 1 :(得分:3)
您正在排序字符串而不是数字。字符串CompareTo
不考虑长度。
编辑(对于您编辑的问题):在对以数字开头的字符串进行排序时,CompareTo
方法的排序很难给出预期的结果,因为它所做的就是按字母顺序排列。
答案 2 :(得分:0)
字符串“1203”小于“801”。您可以尝试在比较之前将字符串转换为数字(如果它们本质上代表数字值)
答案 3 :(得分:0)
这是其他人注意到的预期功能
如果您想要801r, 802x, 892k, 1203a
这样的订单,请执行此操作
public class ListItem : IComparable<ListItem>
{
public int RollNumber { get; set; }
public string Name { get; set; }
public string AdmissionCode { get; set; }
public int CompareTo(ListItem other) {
return ExtractNumbers(this.AdmissionCode).CompareTo(ExtractNumbers(other.AdmissionCode));
}
private int ExtractNumbers(string expr) {
return Convert.ToInt32(String.Join(null,System.Text.RegularExpressions.Regex.Split(expr, "[^\\d]")));
}
}
答案 4 :(得分:0)
如果你想保持简单:
public class ListItem : IComparable<ListItem>
{
public int RollNumber { get; set; }
public string Name { get; set; }
public string AdmissionCode { get; set; }
#region Implementation of IComparable<in ListItem>
public int CompareTo(ListItem other)
{
return this.AdmissionCode.Length != other.AdmissionCode.Length
? this.AdmissionCode.Length.CompareTo(other.AdmissionCode.Length)
: this.AdmissionCode.CompareTo(other.AdmissionCode);
}
#endregion
}