C# 合并列表<;T>;和林克?
我只是想知道是否有一种方法可以用linq合并order对象列表?为了回答这个问题,我把下面的场景浓缩了下来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
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)
});