2013-10-02 118 views
1

我有两个对象列表,每个对象都有属性Recommendation,它本身就是一个'Recommendation'对象列表。我想根据其属性之一对推荐对象进行排序。我想出了这一点:属性的LINQ排序自定义对象列表中的列表列表

TPSqlORs.Where(x => x.Recommendations != null) 
    .ToList() 
    .ForEach(y => y.Recommendations.OrderBy(z => z.PointNumber)); 
SbmReportsORs.Where(x => x.Recommendations != null) 
    .ToList() 
    .ForEach(y => y.Recommendations.OrderBy(z => z.PointNumber)); 

但它会导致在所有原来的名单没有变化,这使我怀疑ToList()只是把一个副本和排序发生在其被执行后会丢失副本。我沿着这些线进行搜索,但显然当它做了一个副本时,新列表包含对原始列表元素的引用,所以肯定它应该对这两个列表进行排序?

+1

请打破你的习惯总是使用'ToList()。ForEach'。 'ToList'从第一个创建一个全新的集合,所以你正在浪费cpu-cycles和更多的内存,只是为了能够使用'List.ForEach'而不是'foreach'。在这种情况下,您甚至可以更加多余地使用它,因为您可以将'OrderBy'直接链接到'Where'后面。 –

+0

“Recommendations”究竟是什么类型? –

+0

@MatthewWatson'List ' – deed02392

回答

2

由于Recommendations事实上是一个List<Recommendation>您可以使用List.Sort()就地对其进行排序:

item.Recommendations.Sort((lhs, rhs) => lhs.PointNumber.CompareTo(rhs.PointNumber)); 

这假定item是包含要排序的Recommendations的对象。

如果在列表Recommendation元素可以为空,你可以处理它是这样的:

item.Recommendations.Sort 
(
    (lhs, rhs) => 
    (lhs == null || rhs == null) 
    ? Comparer<object>.Default.Compare(lhs, rhs) 
    : lhs.PointNumber.CompareTo(rhs.PointNumber) 
); 

详见List.Sort(Comparison<T> comparison)

注意List.Sort()不稳定排序,而Enumerable.OrderBy()是一个稳定的排序,但这种情况不太可能对您的情况不同。你需要意识到不同之处。

[编辑:我已经纳入Jeppe Stig Nielsen的评论下面的代码;我感谢他。]

+0

你能说明如何这将最好从你的经验做'当'项目'在列表'和其中一些项目可能没有建议('null') – deed02392

+2

@ deed02392你的意思是'推荐'本身可以为空吗?然后你可以做一些像'(lhs,rhs)=> lhs == null || rhs == null?比较器.Default.Compare(lhs,rhs):lhs.PointNumber.CompareTo(rhs.PointNumber)'。我假设'PointNumber'是一个不可为空值的类型? –

+0

正确@JeppeStigNielsen,感谢您的更新。这个答案更清晰的IMO。 – deed02392

4

OrderBy不改变排列顺序。如果你想改变顺序,你应该写:

y.Recommendations = y.Recommendations.OrderBy(z => z.PointNumber).ToList() 

阅读OrderBy

+1

您可能还需要'ToList'调用 - 以避免每次访问时重新排序,除此之外。 –

+0

这应该在'ForEach'内吗?如果我按照您所描述的方式进行替换,我会被告知'y'在上下文中不存在。 – deed02392

+0

@ deed02392取代你的'y.Recommendations.OrderBy(z => z。PointNumber)'与线以上 – wudzik

2

OrderBy永远不会改变原来的列表的顺序。它和其他LINQ方法一起是纯函数。他们不修改输入并只创建新的输出。

0

大多数LINQ表达式不会对源进行更改,它们会返回结果集合。

+1

在这里它是'IOrderedEnumerable' – wudzik