gpt4 book ai didi

c# - 用于比较具有复杂实体的两个列表的 LINQ

转载 作者:太空狗 更新时间:2023-10-29 23:23:04 25 4
gpt4 key购买 nike

我们有如下所列的类结构

public class ItemDTO
{
public int ItemID { get; set; }
}


public class CostPageDTO
{
public string CostPageNumber { get; set; }
public List<ItemDTO> Items { get; set; }
}

有两个列表 – 1) 数据库中存在的成本页面和项目列表 2) 用户选择的成本页面

问题

我们需要比较这两个列表并获得一个结果列表,其中包含实际集合和选定集合中不同项目的计数相同的成本页。

为此(在链式方法中)性能最佳的 LINQ 是什么?

预期结果

基于以下场景的预期结果是一个只有 1 个成本页的列表——“C2”(项目匹配)

enter image description here

代码

static void Main(string[] args)
{

List<CostPageDTO> selectedCostPageAndItems = GetSelectedCostPageAndItems();
List<CostPageDTO> actualItems = GetActualItems();

//LINQ code to get the matching count costPages

}


private static List<CostPageDTO> GetSelectedCostPageAndItems()
{
ItemDTO i1 = new ItemDTO();
i1.ItemID = 1;

ItemDTO i2 = new ItemDTO();
i2.ItemID = 2;

ItemDTO i3 = new ItemDTO();
i3.ItemID = 3;


CostPageDTO c1 = new CostPageDTO();
c1.CostPageNumber = "C1";
c1.Items = new List<ItemDTO>();
c1.Items.Add(i1);

CostPageDTO c2 = new CostPageDTO();
c2.CostPageNumber = "C2";
c2.Items = new List<ItemDTO>();
c2.Items.Add(i2);
c2.Items.Add(i3);

//CostPageDTO c2Duplicate = new CostPageDTO();
//c2Duplicate.CostPageNumber = "C2";
//c2Duplicate.Items = new List<ItemDTO>();
//c2Duplicate.Items.Add(i2);
//c2Duplicate.Items.Add(i3);

List<CostPageDTO> selectedCostPageAndItems = new List<CostPageDTO>();
selectedCostPageAndItems.Add(c1);
selectedCostPageAndItems.Add(c2);
//selectedCostPageAndItems.Add(c2Duplicate);

return selectedCostPageAndItems;

}
private static List<CostPageDTO> GetActualItems()
{
ItemDTO i1 = new ItemDTO();
i1.ItemID = 1;

ItemDTO i2 = new ItemDTO();
i2.ItemID = 2;

ItemDTO i3 = new ItemDTO();
i3.ItemID = 3;

ItemDTO i3Duplicate = new ItemDTO();
i3Duplicate.ItemID = 3;

CostPageDTO c1 = new CostPageDTO();
c1.CostPageNumber = "C1";
c1.Items = new List<ItemDTO>();
c1.Items.Add(i1);
c1.Items.Add(i2);
c1.Items.Add(i3);

CostPageDTO c2 = new CostPageDTO();
c2.CostPageNumber = "C2";
c2.Items = new List<ItemDTO>();
c2.Items.Add(i2);
c2.Items.Add(i3);
c2.Items.Add(i3Duplicate);

List<CostPageDTO> actualItems = new List<CostPageDTO>();
actualItems.Add(c1);
actualItems.Add(c2);

return actualItems;

}

最佳答案

这将选择您的预期结果:

方法语法:

var result = selectedCostPageAndItems.SelectMany(scp => actualItems.Where(acp=>acp.CostPageNumber == scp.CostPageNumber),
(scp,acp)=> new {CostPageNumber = scp.CostPageNumber,
scpItems = new HashSet<int>(scp.Items.Select(x=>x.ItemID)),
acpItems = new HashSet<int>(acp.Items.Select(x=>x.ItemID))})
.Where(x => x.scpItems.SetEquals(x.acpItems))
.Select(x => x.CostPageNumber);

查询理解语法:

var result = from cp1 in selectedCostPageAndItems
from cp2 in actualItems
let items1 = new HashSet<int>(cp1.Items.Select(x=>x.ItemID))
let items2 = new HashSet<int>(cp2.Items.Select(x=>x.ItemID))
where cp1.CostPageNumber == cp2.CostPageNumber
&& items1.SetEquals(items2)
select cp1.CostPageNumber;

解释:

查找所有选定的 ( scp ) 和实际的 ( acp ) CostPageDTO 对具有相同的 CostPageNumber

selectedCostPageAndItems.SelectMany(scp => actualItems.Where(acp=>acp.CostPageNumber == scp.CostPageNumber)

对于每个这样的对( scpacp ),选择 CostPageNumber和一组 ItemDTO.ItemID对于选定的 ( scpItems ) 和实际的 ( acpItems ) CostPageDTO

(scp,acp)=> new {CostPageNumber = scp.CostPageNumber,
scpItems = new HashSet<int>(scp.Items.Select(x=>x.ItemID)),
acpItems = new HashSet<int>(acp.Items.Select(x=>x.ItemID))})

最后选择CostPageNumber具有相等集合的那些

Where(x => x.scpItems.SetEquals(x.acpItems)).Select(x => x.CostPageNumber)

HashSet 的创建和比较都是O(n)

关于c# - 用于比较具有复杂实体的两个列表的 LINQ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20635907/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com