.net 列表“;“订购”;故障
我有一个像这样的班,学生坐在里面。 我的位置像B6 B7 B8 B9 B10 B11 如果我在某个类中使用FindAll with(一个oops版本),我会按照这个顺序得到它 在我做之前一切都很好.net 列表“;“订购”;故障,.net,string,.net,String,我有一个像这样的班,学生坐在里面。 我的位置像B6 B7 B8 B9 B10 B11 如果我在某个类中使用FindAll with(一个oops版本),我会按照这个顺序得到它 在我做之前一切都很好 someclass.OrderBy(r => r.location); 然后这个位置变成B10 B11 B6 B7 B8 B9 这里出了什么问题。如果不使用orderBY,我会更好,但有人能告诉我问题的原因吗?orderBY使用字符串排序,而不是数字排序 'B10' < 'B6'
someclass.OrderBy(r => r.location);
然后这个位置变成B10 B11 B6 B7 B8 B9
这里出了什么问题。如果不使用orderBY,我会更好,但有人能告诉我问题的原因吗?orderBY使用字符串排序,而不是数字排序
'B10' < 'B6'
这就是重要的角色(因为B是相同的)。'6'>'1.这是因为字符串被比较为。。。嗯,弦<代码>'1'小于
'6'
,因此词法比较将在该字符处停止
听起来您需要的是a而不是词法排序。orderby工作正常,请注意字符串B10位于字符串B11之前,而字符串B11依次位于B6之前
请注意,您正在尝试订购一个
列表
(或者我是这么认为的),而不是列表
,为了使字符串中的数字按字典顺序排序,需要对它们进行填充,即B6是从左到右的B01yourListObject.OrderBy(r => int.Parse(r.location.SubString(1)));
这是一个解决办法。如果情况要复杂得多,那么您还需要为新创建的Location类创建一个比较器对象。您可以实现自己的自定义比较器
class CustomCompare : IComparer<string>
{
private static readonly char[] _digits = "0123456789".ToArray();
public int Compare(string a, string b)
{
//assuming alpha start, numeric end
var alphaA = a.TrimEnd(_digits);
var alphaB = b.TrimEnd(_digits);
var alphaCompareTo = alphaA.CompareTo(alphaB);
if (alphaCompareTo != 0)
{
return alphaCompareTo;
}
var numericA = int.Parse(a.Substring(alphaA.Length));
var numericB = int.Parse(b.Substring(alphaB.Length));
return numericA.CompareTo(numericB);
}
}
你需要一个自然排序算法。把它称为:
someclass.OrderBy(r => r.location, new EnumerableComparer<String>());
someclass.OrderBy(r=>r.location,新的EnumerableComparer());
我想您的位置
属性(或字段)是字符串
您可以编写比较器,如:
sealed class LocationComparer : Comparer<string>
{
// expect strings like "B3" or "C26"
public override int Compare(string x, string y)
{
int result = x[0].CompareTo(y[0]);
if (result != 0)
return result;
result = ushort.Parse(x.Substring(1)).CompareTo(ushort.Parse(y.Substring(1)));
return result;
}
}
在Someclass
类中,location
具有类型location
。然后您的原始sorted=someclass.OrderBy(r=>r.location)代码>将起作用
两种解决方案都只是草图。我想您应该添加一些健全性检查。它按字母数字顺序排序,因此10在6之前,因为1在6之前。按字符串顺序:B10r
所属的任何类,就是让它实现IComparable
,定义适当的比较方法(涉及位置
)并使用someclass.OrderBy(r=>r)正如多尔·科恩(Dor Cohen)所建议的那样,如果可能的话,使用固定数字也是一个好方法。同意。这补充了我的答案
someclass.OrderBy(r => r.location, new EnumerableComparer<String>());
sealed class LocationComparer : Comparer<string>
{
// expect strings like "B3" or "C26"
public override int Compare(string x, string y)
{
int result = x[0].CompareTo(y[0]);
if (result != 0)
return result;
result = ushort.Parse(x.Substring(1)).CompareTo(ushort.Parse(y.Substring(1)));
return result;
}
}
// this class inherits the IComparable implementation of Tuple`2
sealed class Location : Tuple<char, ushort>
{
public Location(char letter, ushort number)
: base(char.ToUpper(letter), number)
{
}
public Location(string locationString)
: this(letter: locationString[0], number: ushort.Parse(locationString.Substring(1)))
{
}
public override string ToString()
{
return Item1.ToString() + Item2.ToString();
}
}