合并多个自定义对象列表的内容-C# [英] Merge contents of multiple lists of custom objects - C#

查看:41
本文介绍了合并多个自定义对象列表的内容-C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类项目

public class Project 
{   public int ProjectId { get; set; }
    public string ProjectName { get; set; }
    public string Customer { get; set; }
    public string Address{ get; set; }
}

我有3个列表

List<Project> lst1; List<Project> lst2; List<Project> lst3;

lst1 包含具有ProjectId和ProjectName的 Person 对象.

lst1 contains Person objects with ProjectId and ProjectName.

ProjectId = 1,ProjectName ="X",客户=空,地址=空

ProjectId = 2,ProjectName ="Y",客户=空,地址=空

lst2 包含具有ProjectId和Customer的 Person 对象

lst2 contains Person objects with ProjectId and Customer

ProjectId = 1,ProjectName = null,客户="c1",地址= null

ProjectId = 2,ProjectName = null,客户="c2",地址= null

lst3 包含具有ProjectId和Address的 Person 对象

lst3 contains Person objects with ProjectId and Address

ProjectId = 1,ProjectName = null,客户= null,地址="a1"

ProjectId = 2,ProjectName = null,客户= null,地址="a2" .

考虑到每个列表中都有多个这样的记录,并且每个项目的ProjectId为Uniqe,我如何合并/合并这些列表以获取包含合并对象的一个​​列表

Considering there are multiple such records in each list and ProjectId is Uniqe for each project, How can I merge/combine these list to get one list with merged objects

ProjectId = 1,ProjectName ="X",Customer ="c1",地址="a1"

ProjectId = 2,ProjectName ="Y",Customer ="c2",地址="a2"

我发现这些链接很相似,并尝试使用它,但无法达到结果

I found thse links similar and tried with it but could not meet the results

使用linq从两个对象列表创建列表

如何使用LINQ合并两个列表?

谢谢.

推荐答案

可以很简单地通过多步骤方法来完成.首先,定义 Func< Project,Project,Project> 来处理实际的记录合并.也就是说,您正在定义一个具有与 public Project SomeMethod(Project p1,Project p2)等效的签名的方法.此方法实现了您上面概述的合并逻辑.接下来,我们将列表的元素连接在一起,然后按 ProjectId 对其进行分组,使用合并委托作为 GroupBy 的重载中的聚合函数,该函数接受结果选择器:

This could be done in a multi-step approach pretty simply. First, define a Func<Project, Project, Project> to handle the actual record merging. That is, you are defining a method with a signature equivalent to public Project SomeMethod(Project p1, Project p2). This method implements the merging logic you outlined above. Next, we concatenate the elements of the lists together before grouping them by ProjectId, using our merge delegate as the an aggregate function in the overload of GroupBy which accepts a result selector:

Func<Project, Project, Project> mergeFunc = (p1,p2) => new Project
    {
        ProjectId = p1.ProjectId,
        ProjectName = p1.ProjectName == null ? p2.ProjectName : p1.ProjectName,
        Customer = p1.Customer == null ? p2.Customer : p1.Customer,
        Address = p1.Address == null ? p2.Address : p1.Address    
    };

var output = lst1.Concat(lst2).Concat(lst3)
                 .GroupBy(x => x.ProjectId, (k, g) => g.Aggregate(mergeFunc)); 

以下是对上述逻辑以及输出的快速而肮脏的测试:

Here's a quick and dirty test of the above logic along with output:

List<Project> lst1; List<Project> lst2; List<Project> lst3;
lst1 = new List<Project> 
    {
        new Project { ProjectId = 1, ProjectName = "P1" },
        new Project { ProjectId = 2, ProjectName = "P2" },
        new Project { ProjectId = 3, ProjectName = "P3" }
    };
lst2 = new List<Project>
    {
        new Project { ProjectId = 1, Customer = "Cust1"},
        new Project { ProjectId = 2, Customer = "Cust2"},
        new Project { ProjectId = 3, Customer = "Cust3"}
    };
lst3 = new List<Project>
    {
        new Project { ProjectId = 1, Address = "Add1"},
        new Project { ProjectId = 2, Address = "Add2"},
        new Project { ProjectId = 3, Address = "Add3"}
    };

Func<Project, Project, Project> mergeFunc = (p1,p2) => new Project
    {
        ProjectId = p1.ProjectId,
        ProjectName = p1.ProjectName == null ? p2.ProjectName : p1.ProjectName,
        Customer = p1.Customer == null ? p2.Customer : p1.Customer,
        Address = p1.Address == null ? p2.Address : p1.Address    
    };

var output = lst1
    .Concat(lst2)
    .Concat(lst3)
    .GroupBy(x => x.ProjectId, (k, g) => g.Aggregate(mergeFunc));

IEnumerable<bool> assertedCollection = output.Select((x, i) => 
    x.ProjectId == (i + 1) 
    && x.ProjectName == "P" + (i+1) 
    && x.Customer == "Cust" + (i+1) 
    && x.Address == "Add" + (i+1));

Debug.Assert(output.Count() == 3);  
Debug.Assert(assertedCollection.All(x => x == true));

-输出---

IEnumerable<Project> (3 items)   
ProjectId ProjectName Customer Address 
1 P1 Cust1 Add1 
2 P2 Cust2 Add2 
3 P3 Cust3 Add3 

这篇关于合并多个自定义对象列表的内容-C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆