基于其他列合并C#列表中一列的多行
我有一个通用的C#list基于其他列合并C#列表中一列的多行,c#,linq,list,C#,Linq,List,我有一个通用的C#listlistResults,它有几个字段,其中有几行数据,类型如下RESULT public class Result { public int TrdID; public string Term; public double Price; public string Seller; public string Buyer; public bigint Quantity; } 数据如下 TrdID Term
list
Results,它有几个字段,其中有几行数据,类型如下RESULT
public class Result
{
public int TrdID;
public string Term;
public double Price;
public string Seller;
public string Buyer;
public bigint Quantity;
}
数据如下
TrdID Term Price Seller Buyer Quantity
1000 201508 1 ABC XYZ 10
1010 201508 2 ACB PQR 10
1002 201507 1.5 ABX PEW 20
1002 201506 1.5 ABX PEW 20
1002 201508 1.5 ABX PEW 20
现在,我想处理上面的数据,并为特定的
ID
提供一个唯一的ID
返回一个,除了Term
之外,所有列都是相同的。例如,我有三条ID为1002的记录,我想将它们合并为一条记录,方法是将术语转换为日期时间,并引入两个新列,分别是startDate
和EndDate
,预期结果如下
TrdID Term Price Seller Buyer Quantity
1000 201508 1 ABC XYZ 10
1010 201508 2 ACB PQR 10
1002 201507 1.5 ABX PEW 20
1002 201506 1.5 ABX PEW 20
1002 201508 1.5 ABX PEW 20
预期结果
TrdID StartDate EndDate Price Seller Buyer Quantity
1000 08/01/2015 08/31/2015 1 ABC XYZ 10
1010 08/01/2015 08/31/2015 2 ACB PQR 10
1002 06/01/2015 08/31/2015 1.5 ABX PEW 60
从上面的数据可以看出,我有两个新列,分别名为StartDate
和EndDate
,而不是Term
列,后者用于获取StartDate
和EndDate
的值。
此外,最后一行中的数量
发生了变化,这是特定ID的所有数量之和,即,重复ID的次数*数量
在这里,我有两个案件要解决
案例1:
如果特定的ID
只有一条记录,比如说,1000
,则StartDate
将是术语列中当月的第一天,EndDate将是Term
中当月的最后一天。
数量无变化
案例2:
如果一个特定的ID
有多条记录,比如1002
(所有术语将按顺序排列),则StartDate
将是最少月份的第一天,即06/01/2015
,EndDate将是术语列中最高月份的最后一天,即2015年8月31日。
数量=重复ID次数*数量
即20*3=60
我的结果列表将为
public class ProcessedResult
{
public int TrdID;
public DateTime StartDate;
public DateTime EndDate;
public double Price;
public string Seller;
public string Buyer;
public bigint Quantity;
}
我可以知道解决这个问题的好方法吗?如果卖方和买方与您在文章中给出的示例相同,您需要这样的东西:
var result = list.GroupBy( result => result.TrdID)
.Select( gr => {
var startDate = DateTime.ParseExact(gr.OrderBy(x => x.Term).First().Term, "yyyyMM", CultureInfo.InvariantCulture);
var endDate = DateTime.ParseExact(gr.OrderByDescending(x => x.Term).First().Term, "yyyyMM", CultureInfo.InvariantCulture);
return new ProcessedResult
{
TrdID = gr.Key
StartDate = new DateTime(startDate.Year, startDate.Month, 1),
EndDate = (new DateTime(endDate.Year, endDate.Month, 1)).AddMonth(1).AddDays(-1),
Price = gr.First().Price,
Seller = gr.First().Seller,
Buyer = gr.First().Buyer,
Quantity = gr.Sum(x=>x.Quantity)
}
});
从本质上讲,我们根据结果(列表包含您的结果)进行分组。技巧在于如何构造
StartDate
和EndDate
。在这里,我们对同一组中的行进行排序,得到第一行,以获得StartDate
的字符串表示形式。然后我们使用DateTime.ParseExact
方法,因为我们知道DateTime的确切格式。至于EndDate
我们制作了一个OrderByDescending
,为了得到最后一个日期,我们可以制作一个OrderBy并得到最后一个元素,这是等效的。然后我们再次应用DateTime.ParseExact 你试过什么?你被困在哪里GroupBy
、Min
和Max
似乎是使用的合理函数。当有多条记录具有相同的TrdID时,价格、卖方、,买家和数量对于所有记录都是相同的?更正:在mscorlib.dll中发生了类型为“System.FormatException”的未经处理的异常附加信息:字符串未被识别为有效的日期时间。
这是因为术语
是我列表中的一个字符串,我认为这不会给我第一天的起始日期这个月的最后一天是Term string Field中的EndDate,我对您的答案做了一个小改动,通过DateTime.ParseExact(gr.OrderBy(x=>x.Term).first()删除第一条注释中的异常.Term
但这仍然没有给我正确的截止日期为08/31/2015
,而是给了08/01/2015
@Dev您是对的。我的错误:(.请看一看,知道。开始日期和结束日期将再次成为YYYYYYMM
的形式,您如何使用子字符串(4,6)
仅适用于'201508`