我有以下记录
最后2个是记录3和4的子代,我希望能够按金额对记录进行排序,但是应该将非利息(父母)的那些先排序,然后在他们的子代之后出现,例如像这样
2000
2000
20001
99.84 (child of the above)
50000
249.58 (child of the above)
基本上,我希望按金额排序可以忽略将“ IsInterest”设置为true的那一类,但要让它们显示在其父级之后。
我可以先将所有父母带入一个新集合中,然后再通过父母检查是否有孩子,然后在新集合中将它们插入到父母之后来做到这一点,但是我觉得这不是有效且肮脏的代码,所以我以为我会问也许有人知道黑魔法。
排序还应该知道数量上的asc / desc。
我可以发布我的代码,如果有帮助的话,将集合拆开并放在一起,但我尝试尽可能不使用该代码。
我的排序方法使用一个字符串作为“升序”或“降序”,如果有帮助的话
谢谢
更新2
我要指出的是,只有两个级别,孩子将只有一个父母(无祖父母),每个父母最多有一个孩子
根据要求更新代码(字段名称可能与db字段不同。)
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);
一些性能提示:
如果总是有一个孩子或您根本不在乎孩子的顺序,则可以删除
ThenBy(...)
使用
if
语句检查顺序,并使用两个版本的语句-第二个版本使用OrderByDescending
/ ThenByDescending
,并删除三元运算符(desc ? ... : ...
)-否则将对每个项目进行评估对于您当前的解决方案,我不提供任何性能保证-结果可能会更慢。