即使两个列表中都不存在项目,如何获取两个列表中的所有项目?

我有两个可枚举的列表。


List<List_Data> List1 = new List<List_Data>();

List1.Add(new List_Data { Material = "1", Batch = "B1", QTY = 5 });

List1.Add(new List_Data { Material = "1", Batch = "B2", QTY = 5 });

List1.Add(new List_Data { Material = "2", Batch = "B1", QTY = 15 });


List<List_Data> List2 = new List<List_Data>();

List2.Add(new List_Data { Material = "1", Batch = "B1", QTY = 2 });

List2.Add(new List_Data { Material = "3", Batch = "B1", QTY = 5 });

List2.Add(new List_Data { Material = "3", Batch = "B2", QTY = 15 });

我想要的是比较两个列表并根据材料和批次获得差异数量(list1.QTY - list2.QTY)。即使另一个列表中不存在某个项目,我也需要根据该材料和批次获得减号或加号。


这是我期待的输出。


Material = "1", Batch = "B1", QTY = 3

Material = "1", Batch = "B2", QTY = 5 

Material = "2", Batch = "B1", QTY = 15

Material = "3", Batch = "B1", QTY = -5

Material = "3", Batch = "B2", QTY = -15

这是我到目前为止所做的,


SendList = (from l1 in List1

            join l2 in List2 on new { l1.Material, l1.Batch } equals new { l2.Material, l2.Batch } into temp

            from l2 in temp.DefaultIfEmpty()

            select new Report_Class

            {

                Material = l1.Material != null ? l1.Material : l2.Material, 

                Batch = l1.Batch != null ? l1.Batch : l2.Batch, 

                Difference = l1 != null && l2 != null ? (l1.QTY - l2.QTY).ToString() : l1 != null ? l1.QTY.ToString() : l2.QTY.ToString(), 


            }).ToList();

问题是它返回 list1 所有存在的项目,但不返回仅存在于列表 2 中的项目。任何帮助将不胜感激。


谢谢。


拉丁的传说
浏览 163回答 3
3回答

芜湖不芜

这是一种方法:反转QTYList2 上的值将上述结果与 List1 连接起来。按Material和对串联列表进行分组Batch,并对QTY值求和这是代码:var result = List1.Concat(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;List2.Select(list2Item => new List_Data&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Material = list2Item.Material,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Batch = list2Item.Batch,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;QTY = list2Item.QTY * -1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.GroupBy(item => new { item.Material, item.Batch })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.Select(grouped => new List_Data&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Material = grouped.First().Material,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Batch = grouped.First().Batch,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;QTY = grouped.Sum(item => item.QTY)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;})&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.ToList();即使你有 null QTY,它仍然可以工作。例如,具有这些值:List<List_Data> List1 = new List<List_Data>();List1.Add(new List_Data { Material = "1", Batch = "B1", QTY = 5 });List1.Add(new List_Data { Material = "1", Batch = "B2", QTY = 5 });List1.Add(new List_Data { Material = "2", Batch = "B1", QTY = 15 });List1.Add(new List_Data { Material = "3", Batch = "B1", QTY = null });List1.Add(new List_Data { Material = "3", Batch = "B3", QTY = 4 });List<List_Data> List2 = new List<List_Data>();List2.Add(new List_Data { Material = "1", Batch = "B1", QTY = 2 });List2.Add(new List_Data { Material = "3", Batch = "B1", QTY = 5 });List2.Add(new List_Data { Material = "3", Batch = "B2", QTY = 15 });List2.Add(new List_Data { Material = "3", Batch = "B3", QTY = null });将导致:Material: "1", Batch: "B1", QTY: 3Material: "1", Batch: "B2", QTY: 5Material: "2", Batch: "B1", QTY: 15Material: "3", Batch: "B1", QTY: -5Material: "3", Batch: "B3", QTY: 4Material: "3", Batch: "B2", QTY: -15

潇湘沐

如果我们假设在第二个列表中最多(如果有的话)一个具有相同Material和Bacth值的元素,那么一个简单的解决方案可能如下:// Initially project each element in the list to an element that&nbsp;// has also the info in which list this item is contained.var list1 = List1.Select(x => new {Data = x, List = 1});var list2 = List2.Select(x => new {Data = x, List = 2});var result = list1.Concat(list2)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .GroupBy(x => new {x.Data.Batch, x.Data.Material})&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Select(gr =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var itemsInGroup = gr.Count();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (itemsInGroup == 1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var onlyItemInGroup = gr.First();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (onlyItemInGroup.List == 1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return onlyItemInGroup.Data;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Item came from the second list. So multiply it's quantity by -1.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onlyItemInGroup.Data.QTY *= -1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return onlyItemInGroup.Data;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Since for each item in list 1 there is at most one item in the list2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // and vice versa itemsInGroup now is 2 and it is safe to use First as below&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // to grab the items.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var itemFromFirstList = gr.First(x => x.List == 1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var itemFromSecondList = gr.First(x => x.List == 2);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new List_Data&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Material = gr.Key.Material,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Batch = gr.Key.Batch,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; QTY = itemFromFirstList.Data.QTY - itemFromSecondList.Data.QTY&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }).ToList();Select在我们连接两个列表并根据键Material和对结果列表中的项目进行分组之后,基本上所有工作都在内部完成Batch。我们基于最初假设的选项如下:该组仅包含一个项目,该项目来自第一个列表。在这种情况下,我们只返回该项包含的数据。该组仅包含一个项目,该项目来自第二个列表。在这种情况下,我们必须将该值乘以QTY-1。请记住,您要使用的类型是list1.QTY - list2.QTY并且在第一个列表中没有任何关联元素,list1。所以你想得到-list2.QTY你所声明的。该组包含两个项目,因为我们假设一个列表中最多(如果有的话)一个关联元素用于另一个列表中的另一个元素。在这种情况下,我们只需减去list2.QTYfromlist1.QTY即可获得新数量。

至尊宝的传说

这里另一种解决方案var result = List1&nbsp; &nbsp; .Select(e => new&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; key = new&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.Material,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.Batch&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; QTY = e.QTY&nbsp; &nbsp; })&nbsp; &nbsp; .Concat(List2&nbsp; &nbsp; &nbsp; &nbsp; .Select(e => new&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; key = new&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.Material,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.Batch&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; QTY = -e.QTY&nbsp; &nbsp; &nbsp; &nbsp; }))&nbsp; &nbsp; .GroupBy( e => e.key, e => e.QTY )&nbsp; &nbsp; .Select(g => new Report_Class&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Material = g.Key.Material,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; Batch = g.Key.Batch,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; Difference = g.Sum()&nbsp; &nbsp; })&nbsp; &nbsp; .ToList();
打开App,查看更多内容
随时随地看视频慕课网APP