使用linq在组内排序

时间:2015-05-20 10:03:02

标签: c# linq sorting group-by

我有一个对象列表。我想按日期排序,然后按TransParentType排序,然后按TransType排序。然后我想按TransParentType进行分组,并在每个组中放置一个特定项目(如果存在)放在组的底部(撤销:具体)。

示例数据:

Date          TransParentType   TransType

2015/05/20    Purchase      investment
2015/05/20    Redemption    withdrawal: b
2015/05/20    Redemption    zz
2015/05/20    Redemption    withdrawal: a
2015/05/20    Redemption    withdrawal: specific
2015/05/20    Redemption    withdrawal: c   
2015/05/14    Purchase      investment

预期的排序数据:

Date          TransParentType   TransType

2015/05/14    Purchase      investment
2015/05/20    Purchase      investment
2015/05/20    Redemption    withdrawal: a
2015/05/20    Redemption    withdrawal: b
2015/05/20    Redemption    withdrawal: c
2015/05/20    Redemption    withdrawal: specific
2015/05/20    Redemption    zz  

我正在尝试做这样的事情,没有太大的成功。 GroupBy不维护我的排序数据。这是我已经得到的。不确定是否有办法将特定项目移动到组的底部,或者我是否必须手动执行...

results = results.OrderBy(r => r.Date).ThenBy(r=>r.TransParentType)
                             .ThenBy(r => r.TransType).ToList();

var grouped = results.GroupBy(g => g.TransParentType)... 

3 个答案:

答案 0 :(得分:1)

好吧,我从预期的排序数据中看不到该组的需要。

我愿意

results = results.OrderBy(r => r.Date)
                 .ThenBy(r=>r.TransParentType)
                 //just add an order criterion, checking if TransType == the value that you want at the end
                 //as order by a boolean returns false results first, this will put "widthdrawal: specific" at the end
                 //this will only make a difference for the elements starting with "withdrawal:"
                 .ThenBy(r => r.TransType == "widthdrawal: specific")
                 //finally, order TransType for all elements
                 .ThenBy(r => r.TransType)
                 .ToList();

编辑:

根据新规范,我会看到像(<丑闻)那样的东西

        results = results
                     //order by date
                    .OrderBy(m => m.Date)
                    //order by transParentType
                    .ThenBy(m => m.TransParentType)
                     //order by the beginning of TransType (the part which may contain "withdrawal:"
                    .ThenBy(m => m.TransType.Substring(0, Math.Min(11, m.TransType.Length)))
                    .ThenBy(m => m.TransType == "withdrawal: specific")
                    .ThenBy(m => m.TransType);

答案 1 :(得分:1)

我相信这样的事情会起作用:

results = results
    .OrderBy(r => r.Date)
    .ThenBy(r => r.TransParentType)
    .ThenBy(r => r.TransType == "withdrawal: specific" ? 1 : 0)
    .ThenBy(r => r.TransType).ToList();

答案 2 :(得分:0)

您在问题中显示的输出根本不会分组,只是:

results.OrderBy(r => r.TransParentType).ThenBy(r => r.Date).ThenBy(r => r.TransType == "withdrawal: specific").ThenBy(r => r.TransType);

如果我尝试使用您的代码,我发现GroupBy确实维护了顺序,除非显然将它拆分为两个单独的组。

如果GroupBy确实令订单失望(虽然我看不清楚),那么你可以使用:

var groupedResults = results.GroupBy(r => r.Trans‎ParentType).Select(grp => grp.OrderBy(r => r.Date).ThenBy(r => r.TransType == "withdrawal: specific").ThenBy(r => r.TransType));

这将为您提供IEnumerable<OrderedEnumerable<>>,因此您可以foreach遍历每个块,然后foreach再次按顺序排列,依此类推。 (如果针对不同的linq源完成,则为IQueryable<IOrderedQueryable<>>。)