C# 合并列表<;T>;和林克?

C# 合并列表<;T>;和林克?,c#,linq,lambda,C#,Linq,Lambda,我只是想知道是否有一种方法可以用linq合并order对象列表?为了回答这个问题,我把下面的场景浓缩了下来 public class Order { public string Guid { get; set; } public string Parent { get; set; } public string ProductID { get; set; } public string Description { get; set; } public do

我只是想知道是否有一种方法可以用linq合并order对象列表?为了回答这个问题,我把下面的场景浓缩了下来

public class Order
{
    public string Guid { get; set; }
    public string Parent { get; set; }
    public string ProductID { get; set; }
    public string Description { get; set; }
    public double Quantity { get; set; }
    public double Total { get; set; }
}
这将成为基于上述内容的列表,如下所示:

GUID       PARENT       ID         Desc          Qty           Total
====================================================================
aaa                     120        Burger         1            2.50
bbb        aaa          121        + Bacon        1            0.50
ccc                     123        Fries          1            1.50
ddd                     120        Burger         1            2.50
eee        ddd          124        + Cheese       1            0.30
fff                     123        Fries          1            1.50
在这个例子中,我想做的是以以下内容结束

GUID       PARENT       ID         Desc          Qty           Total
====================================================================
aaa                     120        Burger         1            2.50
bbb        aaa          121        + Bacon        1            0.50
ccc                     123        Fries          2            3.00
ddd                     120        Burger         1            2.50
eee        ddd          124        + Cheese       1            0.30
在这里,我不尝试合并项目是否有子产品,以及其他所有项目的总和和数量

我现在的想法是创建一个单独的列表,只列出没有孩子的产品,并与有孩子的产品进行精心的合并


我可以这样做,但我想知道是否有更干净的方法,任何输入都会得到极大的响应

这应该使子订单保持独立,并且只合并独立订单:

var orders = originalOrders.GroupBy(_ => _.parent ? _.parent : _.guid);
var consolidated = orders
    .Where(grp => grp.Count() == 1) // only orders with no children
    .SelectMany(grp => grp)
    .GroupBy(_ => _.ID)
    .Select(grp => grp.Aggregate((a,b) => new order
        {
            guid = a.guid,
            parent = a.parent,
            ProductID = a.ProductID,
            Description = a.Description,
            Quantity = a.Quantity + b.Quantity,
            Total = a.Total + b.Total
        }
));

var allOrders = orders
    .Where(grp => grp.Count() > 1)
    .SelectMany(grp => grp)
    .Concat(consolidated);

这可能会有一些性能问题,但这应该让您开始

如果你想一次性完成这项工作,关键是计算要分组的内容。 因为我们不想将项目与子项分组,所以我们需要一些独特的东西来对这些项目进行分组。如果我们取两个汉堡行,它们唯一不同的是Guid,所以这需要在我们的分组中。如果项目没有子行,则应将其分组。 因此,我们计算一个group子句,如果项有子项,它将成为Guid;如果项没有子项,它将成为空字符串。 然后还需要对ProductID进行分组,因为这是我们想要对没有子项的项目进行分组的内容

var lst = orders.GroupBy(x => new
{
    x.ProductID,
    GuidIfHaveChildren = (orders.Any(x2 => x2.Parent == x.Guid) ? x.Guid : ""),
    x.parent
}).Select(x => new
 {
     Guid = x.First().Guid,
     Parent = x.First().Parent,
     Id = x.Key.ProductID,
     Desc = x.First().Description,
     Qty = x.Sum(p => p.Quantity),
     Total = x.Sum(p => p.Total)
 });

寻找海螺?为什么在添加项目时不添加数量?首先检查该项是否已在该列表中,如果已在该列表中,则将+1添加到数量中..我同意@Spluf-这不是数据的最佳模式。这不是订单-这是订单项目。列表是顺序,但听起来好像它没有提供一个接口来为您提供所需的数据。假设GUID对于每种项目类型都是唯一的,那么最好保留一个
字典作为您的顺序。更好的方法是-包装字典并提供好的命名方法-AddItem、GetItemCount、@spluf,在理想的世界中,这就是我要做的,只是我受到第三方应用程序的限制,不幸的是,我无法控制这看起来还可以,但我认为您忽略了一个条件:
如果项目有子产品,请不要尝试合并。
oops是的,很好!OP应该决定如何处理这种情况,例如,一个带培根的汉堡和一个带奶酪的汉堡是否应该显示为2个汉堡,1个培根,1个奶酪?参考classI订单上的儿童食品会很有帮助。我不会将其合并为2份汉堡1份培根1份奶酪,因为这样很难知道哪个汉堡有什么或一个汉堡同时有什么-这就是为什么不合并儿童食品的原因-我知道很复杂@JazziJeff我编辑了我的答案,以便将订单与孩子分开Hi Mike-抱歉,我现在只想回到这里-您的行var orders=originalOrders.GroupBy(=>uu.parent?u.parent:u.guid);在编译时给我一个无法将类型字符串隐式转换为bool的错误,有什么建议吗?看,谢谢,我似乎遇到了一个问题,从gg在选择新秩序,看看你是否得到一个机会非常接近,但似乎集团的子产品对家长。例如,如果我销售1个汉堡+培根、2个薯条、1个汉堡+培根,则输出为1个汉堡+2个培根、2个薯条、1个汉堡-理想情况下,它应将培根与每个汉堡保持在一起,如果这样做有意义,您能更新示例数据以包含此类案例吗?所以我做对了在这里快速整理一下你的答案,只是为了测试,谢谢。这太完美了,我现在只是测试一些边缘案例,但是很棒的东西
var lst = orders.GroupBy(x => new
{
    x.ProductID,
    GuidIfHaveChildren = (orders.Any(x2 => x2.Parent == x.Guid) ? x.Guid : ""),
    x.parent
}).Select(x => new
 {
     Guid = x.First().Guid,
     Parent = x.First().Parent,
     Id = x.Key.ProductID,
     Desc = x.First().Description,
     Qty = x.Sum(p => p.Quantity),
     Total = x.Sum(p => p.Total)
 });