繁体   English   中英

按多个条件拆分列表

[英]Split list by multiple conditions

这个LINQ和lambda表达式正在杀了我,所以我再次在这里寻求帮助:)

我想要做的是将List<Order>转换为List<List<Order>> ,记住一些事情。

有一些具有ID,货币和Ammount的类Order ,其中仅基本货币在此问题中有一些作用。

class Order
{
    int ID;
    string Currency;
    money Ammount
}

除了Order类之外,还有一些参数用于列表的最大大小。

int MaxListSize = 3;

还有订单清单

List<Order>
{
    1, EUR, 100
    2, EUR, 200
    3, USD, 34
    4, EUR, 12
    5, EUR, 54
    6, USD, 67
    7, EUR, 22
    8, USD, 67
    9, EUR, 89
    10, USD, 64
    11, EUR, 45
    12, USD, 65
    13, USD, 2
    14, EUR, 78
    15, USD, 79
    16, USD, 66
    17, EUR,  3
    18, EUR, 2
}

转型应该是这样的

List<List<Order>>
{
    {1, EUR, 100},  {2, EUR, 200}   {4, EUR, 12}
    {5, EUR, 54},   {7, EUR, 22},   {9, EUR, 89}
    {11, EUR, 45},  {14, EUR, 78},  {17, EUR,  3}
    {18, EUR, 2}
    {3, USD, 34},   {6, USD, 67},   {8, USD, 67}
    {10, USD, 64},  {12, USD, 65},  {13, USD, 2}
    {15, USD, 79},  {16, USD, 66}
}

转换为简单语言此输出列表的每个元素sholud是仅包含相同货币的订单的列表,并且元素列表的最大大小应该是从开始的MaxListSize的参数。

当我在这里时,让我们再添加一点。 让我们假设我们有一些类OrderGroup,表示一行输出转换几行uper,但与List一起它有属性索引。

class OrderGroup
{
    List<Order> OrderList
    int ListIndex
}

输出应该是

List<OrderGroup>
{
     GroupOrder {OrderList = new List<Order> {{1, EUR, 100},    {2, EUR, 200}   {4, EUR, 12}}, ListIndex  = 1}
     GroupOrder {OrderList = new List<Order> {{5, EUR, 54}, {7, EUR, 22},   {9, EUR, 89}},  ListIndex  = 2}
     GroupOrder {OrderList = new List<Order> {{11, EUR, 45},    {14, EUR, 78},  {17, EUR,  3}}, ListIndex  = 3}
     GroupOrder {OrderList = new List<Order> {{18, EUR, 2}}, ListIndex  = 4}
     GroupOrder {OrderList = new List<Order> {{3, USD, 34}, {6, USD, 67},   {8, USD, 67}}, ListIndex  = 1}
     GroupOrder {OrderList = new List<Order> {{10, USD, 64},    {12, USD, 65},  {13, USD, 2}}, ListIndex  = 2}
     GroupOrder {OrderList = new List<Order> {{15, USD, 79},    {16, USD, 66}}, ListIndex  = 3}
}

输出与第一个基本相同,加上索引,应该取决于货币。 每种货币都有自己的零基指数。

任何帮助都会被高估。 我知道它应该用Select()或SelectMany()扩展方法以某种方式完成,但我不知道如何。

提前Thanx :)

这基本上是@ BrokenGlass的答案,为完整性添加了GroupBySelectMany

var results = orders.GroupBy(o => o.Currency)
                    .SelectMany(g => g.Select((order, index) => new { Index = index, Order = order })
                                      .GroupBy(x => x.Index / MaxListSize)
                                      .Select(og => new OrderGroup() 
                                      {
                                         ListIndex = og.Key,
                                         OrderList = og.Select(x => x.Order).ToList()
                                       })
                                      .ToList())
                    .ToList();

为了确保一般情况下的正确顺序,您可以在查询开头添加.OrderBy(o => o.ID)子句。 但是在您的测试示例中无关紧要。

要对列表进行分组,应该使用以下内容:

var orderGroups = orders.Select((order, index) => new { Index = index, Order = order })
                        .GroupBy(x => x.Index / MaxListSize)
                        .Select(g => g.Select(x => x.Order).ToList())
                        .ToList();

转换为OrderGroup现在很简单:

var orderGroups = orders.Select((order, index) => new { Index = index, Order = order })
                        .GroupBy(x => x.Index / MaxListSize)
                        .Select(g => new OrderGroup() 
                         {
                            ListIndex = g.Key,
                            OrderList = g.Select(x => x.Order).ToList())
                         })
                        .ToList();

这是一个棘手的选择,但它做你需要做的事情:

var res = orders
    .GroupBy(o => o.Currency)
    .SelectMany(g => g.Select((o,i) => new {Ind = i, Order = o}))
    .GroupBy(p => new { Num = p.Ind/3, Curr = p.Order.Currency })
    .Select(g => new OrderGroup {ListIndex = g.Key.Num, OrderList = g.Select(x => x.Order).ToList()})
    .ToList();
foreach (var list in res) {
    Console.Write(list.ListIndex);
    foreach (var order in list.OrderList) {
        Console.Write("   {0} {1} {2};", order.ID, order.Currency, order.Ammount);
    }
    Console.WriteLine();
}

运行此命令会产生以下输出:

0   1 EUR 100;   2 EUR 200;   4 EUR 12;
1   5 EUR 54;   7 EUR 22;   9 EUR 89;
2   11 EUR 45;   14 EUR 78;   17 EUR 3;
3   18 EUR 2;
0   3 USD 34;   6 USD 67;   8 USD 67;
1   10 USD 64;   12 USD 65;   13 USD 2;
2   15 USD 79;   16 USD 66;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM