Paul W.
Paul W.

Reputation: 299

C# Merge List of sub objects from parent level Object List

If you had a List and wanted to merge the sub List for any SomeObject's that have the same Id field how would you do that? Here are the example objects:

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; }
}

And this is the sample creation of a mock list:

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"
                    }
                }
            }
        };

What sort of Linq or related query would you need to do to create a new list of SomeObject that is merged based on any top level SomeObject's that have matching Id fields; to then combine their KeyPair list to a single list. So you would have SomeObject Id=5 and then 4 key pair values merged from the two different previous SomeObject's in the list. The name value could be left out from the new object.

Any ideas? Thank you so much.

Upvotes: 5

Views: 3114

Answers (3)

Bojan Komazec
Bojan Komazec

Reputation: 9526

You can try this:

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

Original post:

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

Upvotes: 2

Jins Peter
Jins Peter

Reputation: 2469

Use this function

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 SomeObject{Id = x, ValuePairs = newValuePairList});
        });

        return newSomeObjects;
    }

Upvotes: 0

Ruben Vardanyan
Ruben Vardanyan

Reputation: 1308

You need to group them by Id and use SelectMany to select KeyPair list.

var result = objects.GroupBy(o => o.Id).Select(group => new SomeObject
{
    Id = group.Key,
    ValuePairs = group.SelectMany(x => x.ValuePairs).ToList()
}).ToList();

Upvotes: 5

Related Questions