使用实例查询列表,查找一个ID的计数,并合并两个相似ID的内容

本文关键字:ID 合并 相似 两个 一个 查询 实例 列表 查找 | 更新日期: 2023-09-27 18:04:30

我有一个通用的c#列表List<object> Results,它有几个字段,其中有几行数据,如下所示

List<object> Results

数据:

TrdID    Date       Price Seller Buyer  Side
1000     7/23/2015   1     ABC    NULL   2 
1000     7/23/2015   1     NULL   XYZ    1
1002     7/22/2015   1.5   NULL   ABC    1
1002     8/22/2015   1.5   NULL   ABC    1
1002     7/22/2015   1.5   XYZ    NULL   2
1002     8/22/2015   1.5   XYZ    NULL   2
1010     8/23/2015   2     ACB    NULL   2 
1010     8/23/2015   2     NULL   PQR    1

上面的列表有id重复的记录,我想合并IDs重复两次的记录。具有相同IDs的两条记录将具有相同的值,除了SellerBuyer,其中SellerNULL, Side=1Buyer为NULL,当Side=2时,并将它们合并为一条记录,将NULL值替换为随后的另一侧,结果列表将如下

预期结果

TrdID    Date       Price Seller Buyer  
1000     7/23/2015   1     ABC    XYZ  
1010     8/23/2015   2     ACB   PQR

从上面的结果可以看出,IDs 1000 and 1010重复了两次,所以它合并了它们的SellerBuyer值,而ID 1002因为它们的Count不是2而被丢弃

我可以知道解决这个问题的方法吗?

使用实例查询列表,查找一个ID的计数,并合并两个相似ID的内容

您可以使用GroupBy和其他LINQ方法:

Results = Result.GroupBy(x => new { x.TrdID, x.Date, x.Price })
    .Where(g => g.Count() == 2)
    .Select(g => new object 
    {
          TrdID  = g.Key.TrdID,
          Date   = g.Key.Date,     
          Price  = g.Key.Price,
          Seller = g.First(x => x.Seller != null).Seller,
          Buyer  = g.First(x => x.Buyer  != null).Buyer 
    })
    .ToList();

这假定总是有一个Seller不为空,也总是有一个Buyer不为空。如果不是这样,你会得到一个有意义的InvalidOperationException: "Sequence contains no matching element"。

所以如果可能的话,你可以分配null而不是使用属性:

....
Seller = g.Where(x => x.Seller != null)
          .Select(x => x.Seller)
          .FirstOrDefault(),
Buyer  = g.Where(x => x.Buyer != null)
          .Select(x => x.Buyer)
          .FirstOrDefault(),

假设您的对象在类中匹配如下内容:

public class Result
{
    public int TrdID { get; set; }
    public DateTime Date { get; set; }
    public decimal Price { get; set; }
    public string Seller { get; set; }
    public string Buyer { get; set; }
}

然后您可以通过按TrdID值分组来查询您的列表:

var groupedResults = Results
    .GroupBy(r => new { r.TrdID, r.Date, r.Price })
    .Where(g => g.Count() == 2)
    .Select(g => new Result
    {
        TrdID = g.Key.TrdID,
        Date = g.Key.Date,
        Price = g.Key.Price,
        Seller = g.First(x => x.Seller != null).Seller,
        Buyer = g.First(x => x.Buyer != null).Buyer
    });

注意:您需要将Results变量设置为List<Result>才能正常工作,或者先使用Results.Cast<Result>()

试试这样:

(from r in Results
group r by TrdID into g
where g.Count() == 2
let g1 = g.First()
let g2 = g.Last()
select new {
    TrdId = g.Key,
    Date = g1.Date,
    Price = g1.Price,
    Seller = g1.Seller ?? g2.Seller,
    Buyer = g1.Buyer ?? g2.Buyer
})

需要键入'Result'列表,以便'TrdId', 'Date'等字段在查询中可用。