列表<>;按对象属性排序
本文关键字:对象 属性 排序 lt gt 列表 | 更新日期: 2023-09-27 18:29:40
我需要根据对象的一个属性对对象列表进行排序,但它是一个字符串,需要像整数一样进行排序。这些对象是自定义的"属性"对象,其中属性名称(Property.name)是字符串,但90%的属性名称实际上是数字,而其他10%是名称/字母(因此,变量本身必须是字符串,而不是整数)。
我知道我可以使用
propertyList.OrderBy(x => x.Name)
但这会对它进行排序,就好像它是一个字符串一样(即15000"大于"20)。
出于排序目的,我已经将列表拆分为两个单独的列表(一个包含所有属性名称包含字母的列表,另一个包含可以转换为整数的列表),但我不知道如何对"整数"列表进行排序。
我试过这个,但它不起作用,但有这样的东西我可以用吗?
propertyList.OrderBy(x => Convert.ToInt32(x.Name))
您不需要将数据拆分为两个列表;还要注意,您可以在lambda方法中执行复杂的操作,只需要使用不同的语法:
IEnumerable<TItem> sorted = propertyList.OrderBy( x => {
Int32 asInt;
if( Int32.TryParse( x.Name, NumberStyles.Integer, CultureInfo.InvariantCulture, out asInt ) ) {
return asInt;
}
if( x.Name.Length > 0 ) return (Int32)x.Name[0];
return 0;
});
请注意,这段代码有点难看和不完美,因为如果两个文本名称以相同的字符开头,它将无法正确排序。我建议使用更高级的OrderBy
过载:
class NameComparer : IComparer<String> {
public Int32 Compare(String x, String y) {
// put Name comparison logic here
}
}
IEnumerable<TItem> sorted = propertyList.OrderBy( x => x.Name, new NameComparer() );
这里还不清楚您到底想要什么。您想要原始数据的有序视图吗?还是您真的想修改原始数据以便对其进行排序?
如果是前者,那么OrderBy()
方法就是您想要的。听起来你很好地将数字名称与非数字名称分开排序,但在这种情况下,当你尝试第二个代码示例时,你不清楚"它不起作用"是什么意思。该表达式应该可以正常工作,并且可以提供数据的有序视图。例如
foreach (var x in propertyList.OrderBy(x => int.Parse(x.Name))
{
// do something with the ordered elements
}
如果你想实际订购原始数据,那么你可以使用List<T>.Sort()
方法:
propertyList.Sort((x, y) => int.Parse(x.Name).CompareTo(int.Parse(y.Name));
请注意,在List<T>
示例中,从字符串到int的转换是重复进行的。对于相对较小的集合来说,这应该不是问题,但如果性能成为问题,则最好使用LINQ OrderBy()
方法(为您缓存密钥)。您可以使用ToList()
和OrderBy()
将结果具体化为List<T>
。
当然,这涉及到中间数据结构的开销,所以这样做没有什么意义,除非你有一个真正的性能问题需要解决,和你已经证明了这种替代方案可以解决这个问题。