我有以下记录
最后 2 个是记录 3 和 4 的子记录,我希望能够按金额对记录进行排序,但应该首先对非兴趣( parent )记录进行排序,然后再对他们的记录进行排序 children 应该在之后出现,例如它会像这样
2000
2000
20001
99.84 (child of the above)
50000
249.58 (child of the above)
基本上,我希望按金额排序忽略“IsInterest”设置为 true 的排序,但让它们显示在其父级之后。
我可以通过首先将所有父级放入一个新集合中来做到这一点..然后遍历父级以查看是否有任何子级,然后将它们插入到新集合中的父级之后,但我觉得这既不高效又肮脏代码所以我想我会问也许有人知道黑魔法。 排序还应该注意金额的升序/降序。
如果有帮助的话,我可以发布将集合分开并将其组合在一起的代码,但如果可能的话,我会尽量不使用该代码。
如果有帮助的话,我的排序方法采用“升序”或“降序”字符串
谢谢
更新2 我要指出的是,只会有 2 个级别,并且 children 将只有一位 parent (没有祖 parent ),并且每个 parent 最多有 1 个 child
更新代码(字段名称可能与数据库字段不同..)
switch (sortMember.ToUpper())
{
case "AMOUNT":
{
//check to see if any imputed interests exist
if (contributions.Any(x => x.IsImputedInterest))
{
var children = contributions.Where(x => x.IsImputedInterest);
var sortedColl = contributions.Where(x => x.IsImputedInterest == false).OrderByWithDirection(x => x.ContributionAmount, sortDirection.ToUpper() == "DESCENDING").ToList();
foreach (var child in children )
{
//find the parent
var parentIndex = sortedColl.FindIndex(x => x.ContributionId == child.ParentContirbutionId);
sortedColl.Insert(parentIndex+1, child);
}
}
else
{
contributions = contributions.OrderByWithDirection(x => x.ContributionAmount, sortDirection.ToUpper() == "DESCENDING");
}
break;
}
}
........................
public static IOrderedEnumerable<TSource> OrderByWithDirection<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, bool descending)
{
return descending ? source.OrderByDescending(keySelector)
: source.OrderBy(keySelector);
}
public static IOrderedQueryable<TSource> OrderByWithDirection<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool descending)
{
return descending ? source.OrderByDescending(keySelector)
: source.OrderBy(keySelector);
}
最佳答案
这是一个单语句 Linq 解决方案:
var desc = order == "descending";
var result = list
//group parents with it's children
.GroupBy(x => x.ParentId ?? x.Id)
//move the parent to the first position in each group
.Select(g => g.OrderBy(x => x.ParentId.HasValue).ThenBy(x => desc ? -x.Amount : x.Amount))
//sort the groups by parents' amounts
.OrderBy(g => desc ? -g.First().Amount : g.First().Amount)
//retrieve the items from each group
.SelectMany(g => g);
一些性能提示:
- 如果总是最多有一个 child 或者您不关心 child 的顺序,您可以删除
ThenBy(...)
- 使用
if
语句检查顺序,并有两个版本的语句 - 第二个版本使用OrderByDescending
/ThenByDescending
,然后删除三元运算符 (desc ? ... : ...
) - 否则将为每个项目进行评估
对于与您当前的解决方案相关的性能,我不提供任何保证 - 它可能会变得更慢。
关于c# - Linq 排序的一些改进,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33067028/