我需要按对象属性之一对对象列表进行排序,但它是一个需要排序的字符串,好像它是一个整数。对象是自定义的"属性"属性名称(property.Name)是字符串的对象,但是90%的属性名称实际上是数字,而另外10%是名称/字母(因此变量本身必须是字符串而不是整数)。
我知道我可以使用
propertyList.OrderBy(x => x.Name)
...但是,它会将它看作是一个字符串(即15000是"更大"而不是20)。
出于排序目的,我已经将列表分成两个单独的列表(一个包含所有包含字母的属性名称,另一个包含可以转换为整数的列表),但我不知道#39;不知道如何排序"整数"列表。
我已经尝试了这个并且它不起作用,但是我可以使用这样的东西吗?
propertyList.OrderBy(x => Convert.ToInt32(x.Name))
答案 0 :(得分:4)
您无需将数据拆分为两个列表;还要注意,您可以在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() );
答案 1 :(得分:0)
目前尚不清楚你真正想要的是什么。您想要原始数据的有序视图吗?或者你真的想修改原始数据以便订购吗?
如果是前者,那么OrderBy()
方法就是你想要的。听起来你很好地将数字名称与非数字名称分开,但在这种情况下,当你尝试第二个代码示例时,它不清楚你的意思是“它不起作用”。该表达式应该可以正常工作,并提供有序的数据视图。 E.g。
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>
。
当然这涉及到中间数据结构的开销,所以除非你有一个真正证明的性能问题需要解决这个问题,否则没有什么意义,和你已经证明了这个替代方案修复了问题。