列表<>;按对象属性排序

本文关键字:对象 属性 排序 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>

当然,这涉及到中间数据结构的开销,所以这样做没有什么意义,除非你有一个真正的性能问题需要解决,你已经证明了这种替代方案可以解决这个问题。