Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 按多个条件拆分列表_C#_Linq_Lambda - Fatal编程技术网

C# 按多个条件拆分列表

C# 按多个条件拆分列表,c#,linq,lambda,C#,Linq,Lambda,这个LINQ和lambda表达式快把我累死了,所以我再次在这里寻找帮助:) 我想做的是将列表转换为列表,在脑子里只想着几件事 有一个类Order带有ID、Currency和amount,其中basicaly only Currency在这个问题中有一些作用 class Order { int ID; string Currency; money Ammount } 除了Orderclass之外,还有一些用于列表最大大小的参数 int MaxListSize = 3;

这个LINQ和lambda表达式快把我累死了,所以我再次在这里寻找帮助:)

我想做的是将
列表
转换为
列表
,在脑子里只想着几件事

有一个类
Order
带有ID、Currency和amount,其中basicaly only Currency在这个问题中有一些作用

class Order
{
    int ID;
    string Currency;
    money Ammount
}
除了
Order
class之外,还有一些用于列表最大大小的参数

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
}
列表
{
1欧元,100欧元
2欧元,200欧元
3美元,34美元
4欧元,12欧元
5欧元,54欧元
6美元,67美元
7欧元,22欧元
8美元,67美元
9欧元,89欧元
10美元,64美元
11欧元,45欧元
12美元,65美元
13美元,2美元
14欧元,78欧元
15美元,79美元
16美元,66美元
17欧元,3欧元
18欧元,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}
}
列表
{
{1,欧元,100},{2,欧元,200}{4,欧元,12}
{5欧元,54欧元,{7欧元,22欧元,{9欧元,89欧元}
{11,欧元,45},{14,欧元,78},{17,欧元,3}
{18欧元,2}
{3美元,34},{6美元,67},{8美元,67}
{10美元,64},{12美元,65},{13美元,2}
{15美元,79},{16美元,66}
}
翻译成简单语言后,此输出列表的每个元素都应该是仅包含相同货币的订单的列表,并且元素列表的最大大小应该是从开始的参数MaxListSize

当我在这里的时候,让我们再加一点。让我们假设我们有一些类OrderGroup,它表示输出转换的一项,上面有几行,但它和列表一起有属性索引

class OrderGroup
{
    List<Order> OrderList
    int ListIndex
}
class命令组
{
列表订单列表
整型列表索引
}
输出应该是

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}
}
列表
{
GroupOrder{OrderList=新列表{{1,EUR,100},{2,EUR,200}{4,EUR,12}},ListIndex=1}
GroupOrder{OrderList=新列表{{5,EUR,54},{7,EUR,22},{9,EUR,89},ListIndex=2}
GroupOrder{OrderList=新列表{{11,EUR,45},{14,EUR,78},{17,EUR,3}},ListIndex=3}
GroupOrder{OrderList=新列表{{18,EUR,2}},ListIndex=4}
GroupOrder{OrderList=新列表{{3,USD,34},{6,USD,67},{8,USD,67}},ListIndex=1}
GroupOrder{OrderList=新列表{{10,USD,64},{12,USD,65},{13,USD,2}},ListIndex=2}
GroupOrder{OrderList=新列表{{15,USD,79},{16,USD,66},ListIndex=3}
}
产出和第一项基本相同,另外还有指数,这应该取决于货币。每种货币都有自己的零基指数

任何帮助都会被感激的。我知道应该用Select()或SelectMany()扩展方法来实现,但我不知道如何实现


Thanx Prevance:)

要对列表进行分组,类似这样的方法应该可以:

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;

这基本上是@BrokenGlass的答案,添加了一个
GroupBy
和一个
SelectMany
,以确保完整性:

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)
子句。但这在您的测试示例中并不重要

也许您应该添加一个排序部分以确保完整性。首先按
货币
排序,然后按
ID
排序似乎就足够了。@pad:您仍然可以使用边缘大小写,即一个列表包含多个货币的项目,因此这不足够。我将按
货币
对列表进行排序,按
货币
分组,对内部列表进行拆分,并将其收集到一个大列表中。OP希望在输出中将
欧元
美元
分开。@BrokenGlass Fast我必须说,但没有做到这一点。我已经实施了你的解决方案,但我有6个而不是7个项目作为结果,并在一个列表中得到混合欧元和美元的订单,这是不好的。第二,看看输出中的第四个列表,它只有一个项目。非常好!您需要重命名
SelectMany
中的内部
g
,因为它与外部
g
冲突,并删除
OrderList=g.Select(x=>x.Order.ToList())
赋值末尾的额外
,以使其编译。但是除了这些简单的打字错误,它产生了正确的结果。就是这样。谢谢!现在我必须了解该查询中到底发生了什么,以及如何得到正确的结果:)