C#合并来自父级对象列表的子对象列表

Posted

技术标签:

【中文标题】C#合并来自父级对象列表的子对象列表【英文标题】:C# Merge List of sub objects from parent level Object List 【发布时间】:2017-09-24 19:32:35 【问题描述】:

如果您有一个列表并且想要合并任何具有相同 Id 字段的 SomeObject 的子列表,您会怎么做?以下是示例对象:

public class SomeObject

    public string Name  get; set; 
    public int Id  get; set; 
    public List<KeyPair> ValuePairs get;set; 


public class KeyPair

    public string Key  get; set; 
    public string Value  get; set; 

这是模拟列表的示例创建:

List<SomeObject> objects = new List<SomeObject>();
        objects = new List<SomeObject>()
        
            new SomeObject
            
                Name="Rando Object 1",
                Id=5,
                ValuePairs=new List<KeyPair>()
                
                    new KeyPair
                    
                        Key="TestKey1",
                        Value="TestValue1"
                    ,
                    new KeyPair
                    
                        Key="TestKey2",
                        Value="TestValue2"
                    
                
            ,
            new SomeObject
            
                Name="Rando Object 2",
                Id=5,
                ValuePairs=new List<KeyPair>()
                
                    new KeyPair
                    
                        Key="TestKey3",
                        Value="TestValue3"
                    ,
                    new KeyPair
                    
                        Key="TestKey4",
                        Value="TestValue4"
                    
                
            
        ;

您需要执行哪种 Linq 或相关查询来创建新的 SomeObject 列表,该列表基于具有匹配 Id 字段的任何*** SomeObject 进行合并;然后将他们的 KeyPair 列表组合成一个列表。因此,您将拥有 SomeObject Id=5,然后从列表中的两个不同的先前 SomeObject 合并 4 个密钥对值。名称值可以从新对象中省略。

有什么想法吗?非常感谢。

【问题讨论】:

【参考方案1】:

您需要将它们按Id 分组并使用SelectMany 选择KeyPair 列表。

var result = objects.GroupBy(o => o.Id).Select(group => new SomeObject

    Id = group.Key,
    ValuePairs = group.SelectMany(x => x.ValuePairs).ToList()
).ToList();

【讨论】:

这太棒了!【参考方案2】:

你可以试试这个:

var res = objects.GroupBy(o => o.Id)
                 .Select(group => new  
                    Id = group.Key, 
                    ValuePairs = group.SelectMany(g => g.ValuePairs)
                  );

原帖:

var res = objects.Where(o => o.Id == 5).SelectMany(o => o.ValuePairs);

【讨论】:

这将返回KeyPair的列表,但他需要有SomeObject的列表和IdKeyPair的分组列表 正确,我将编辑答案并遵守 OP 要求,从新对象中省略 Name【参考方案3】:

使用此功能

https://dotnetfiddle.net/aE6p5H

public List<SomeObject> MergeObj(List<SomeObject> someObjects)
    
        var idList = someObjects.Select(x => x.Id).Distinct().ToList();
        var newSomeObjects = new List<SomeObject>();
        idList.ForEach(x =>
        
            var newValuePairList = new List<KeyPair>();
            someObjects.Where(y => y.Id == x).ToList().ForEach(y =>
            
                newValuePairList.AddRange(y.ValuePairs);
            );
            newSomeObjects.Add(new SomeObjectId = x, ValuePairs = newValuePairList);
        );

        return newSomeObjects;
    

【讨论】:

以上是关于C#合并来自父级对象列表的子对象列表的主要内容,如果未能解决你的问题,请参考以下文章

JsonIgnore 来自父级的子属性

Thinkcmf子栏目获取父级栏目所有子栏目列表

在 jQuery 中向上移动多个父级 - 更有效的方式?

SQL查询以选择在同一列中具有不同值的子记录的父级

Unity c# Photon - 设置 PhotonNetwork.Instantiate 对象的父级

MongoDB:使用子代数组填充父代vs通过父代ID搜索子代