【问题标题】:How to consolidate results from multiple IEnumerable<T> using LINQ如何使用 LINQ 合并来自多个 IEnumerable<T> 的结果
【发布时间】:2011-04-26 14:34:00
【问题描述】:

我可以拥有多个(最多 5 个)IEnumerable&lt;ResortSupplier&gt;,并希望通过供应商代码将它们合并为单个 IEnumerable&lt;ResortSupplier&gt; 分组。我的对象如下所示:

这是我的对象:

[Serializable]
public class ResortSupplier
{
    public string SupplierCode { get; set; }
    public IList<Product> ResortProducts { get; set; }
}

[Serializable]
public class Product
{
    public string Code { get; set; }
    //Other fields... 
    public IList<PerPricing> PricingDetail { get; set; }
}

[Serializable]
public class PerPricing
{
    //Other fields..
    public decimal? Price { get; set; }
    public Error PricingError { get; set; }
}

多个 IEnumerable 中的数据可能如下所示:

----------------------------------------
IEnumerable<ResortSupplier> - 1

Hyatt Resort
  Standard Room
    PricingDetail-1
  Superior Room         
    PricingDetail-1

Sandals Resort
  Standard Room
    PricingDetail-1
  Delux Room            
    PricingDetail-1

----------------------------------------
IEnumerable<ResortSupplier> - 2

Hyatt Resort
  Standard Room
    PricingDetail-2
  Superior Room         
    PricingDetail-2
  One Bed Room Suit
    PricingDetail-2

Sandals Resort
  Standard Room
    PricingDetail-2
  Honeymoon Suit            
    PricingDetail-2
----------------------------------------
IEnumerable<ResortSupplier> - 3
.....
----------------------------------------
IEnumerable<ResortSupplier> - 4
.....
----------------------------------------
IEnumerable<ResortSupplier> - 5
.....
----------------------------------------

我的合并结果应包含:

IEnumerable<ResortSupplier> - Consolidated

Hyatt Resort
  Standard Room
    PricingDetail-1
    PricingDetail-2
  Superior Room         
    PricingDetail-1
    PricingDetail-2
  Bed Room Suit
    PricingDetail-2

Sandals Resort
  Standard Room
    PricingDetail-1
    PricingDetail-2
  Delux Room            
    PricingDetail-1
  Honeymoon Suit            
    PricingDetail-2

----------------------------------------

处理此问题的最佳方法是什么?我尝试了简单的 IEnumerable.Union 和 GroupBy 子句,但没有得到我想要的结果。

【问题讨论】:

  • FYI Union 将删除重复项。

标签: c# linq ienumerable


【解决方案1】:

如果我理解你,你应该使用 Concat 将它们放入一个大集合中,然后你可以随意分组

IEnumerable<ResortSupplier> master = 
    result1.Concat(result2).Concat(result3); //etc

然后像往常一样分组:

var resultGrouped = master.GroupBy(rs => rs.SupplierCode);

【讨论】:

  • 亚当,请。请参阅我的 cmets 以获取 Martinho 的帖子。
  • 我认为您的问题措辞不正确。对你的 5 个集合调用 concat 会将它们合二为一。对这个庞大的集合进行分组将...按您指定的任何内容对其进行分组。您到底在期待什么以及正在发生什么?
  • 亚当,可能是我在提出问题时没有说得很清楚,但我的例子显示了我的预期结果应该是什么。我为混乱道歉。 Ani 的解决方案对我有用。谢谢。
【解决方案2】:

我想你想要这样的东西:

// You can construct this with an array if it isn't already in this form.
IEnumerable<IEnumerable<ResortSupplier>> supplierLists = ...

var query = from suppliers in supplierLists
            from supplier in suppliers
            group supplier by supplier.SupplierCode into g

            let products = g.SelectMany(s => s.ResortProducts)
                            .GroupBy(p => p.Code)
                            .Select(prodGroup => new Product
                                    {
                                       Code = prodGroup.Key,
                                       PricingDetail = prodGroup
                                                       .SelectMany(p => p.PricingDetail)
                                                       .ToList()
                                    })

            select new ResortSupplier
            {
                SupplierCode  = g.Key, 
                ResortProducts = products.ToList()                              
            };

不过,这是一个看起来非常可怕的查询。我强烈建议将查询的不同组件分解为单独的(命名良好的)方法。

【讨论】:

  • 阿尼,我可以有多个IEnumerable&lt;ResortSupplier&gt;,但不能有IEnumerable&lt;IEnumerable&lt;ResortSupplier&gt;&gt;。你想让我先从所有IEnumerable&lt;ResortSupplier&gt; 构建IEnumerable&lt;IEnumerable&lt;ResortSupplier&gt;&gt; 吗?
  • @Alex:是的。例如:var supplierLists = new[] { supplierList1, supplierList2, ... };
  • 阿尼,这行得通。谢谢。我在ResortSupplier 中还有一个“LowestPrice”字段,其中包含所有 p.PricingDetail 中的最低价格。我怎样才能填充这个字段?我想我可能不得不使用 LINQ 的.Min(p =&gt; p.Price) 函数,但我很难构建查询。
  • 我得到了最低价格 SelectMany(p =&gt; p.PricingDetail).Min(p =&gt; p.Price) 但我想要最低的非零价格,如果我使用诸如 .Where(l =&gt; l.Price &gt; 0).Min(p =&gt; p.Price) 之类的 where 子句,它将删除价格为零的项目,where 子句充当过滤器并删除非零记录。我想保持所有记录完好无损,并获得最低的非零价格。
猜你喜欢
  • 2018-02-26
  • 1970-01-01
  • 2017-04-14
  • 2012-09-17
  • 2010-10-10
  • 1970-01-01
  • 2020-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多