locked
need to group data based on `InstanceData` Name property RRS feed

  • Question

  • Hello,

    I have one Packet like below,

    var dataPacket = new Packet
                {
                    Id = new Guid("2e08bd98-68eb-4358-8efb-9f2adedfb034"),
                    Results = new Result
                    {
                        ResultName = "ResultName1",
                        Instances = new List<Instance>
                        {
                            new Instance
                            {
                                InstanceName = "InstanceName1",
                                InstanceDatas = new List<InstanceData>
                                {
                                    new InstanceData{Name = "N1", Value = "V1"},
                                    new InstanceData{Name = "N2", Value = "V2"}
                                }
                            },
                            new Instance
                            {
                                InstanceName = "InstanceName2",
                                InstanceDatas = new List<InstanceData>
                                {
                                    new InstanceData{Name = "N1", Value = "V3"},
                                    new InstanceData{Name = "N2", Value = "V4"}
                                }
                            }
                        }
                    }
                };

    Here are the class structures,

    public class Packet
        {
            public Guid Id { get; set; }
            public Result Results { get; set; }
        }
    
        public class Result
        {
            public string ResultName { get; set; }
            public List<Instance> Instances { get; set; }
        }
    
        public class Instance
        {
            public string InstanceName { get; set; }
            public List<InstanceData> InstanceDatas { get; set; }
        }
    
        public class InstanceData
        {
            public string Name { get; set; }
            public string Value { get; set; }
        }

    For above Packet I want to spilt this into 2 Packets based on InstanceData common Name

    • All N1 from InstanceName1 and InstanceName2 into one packet
    • All N2 from InstanceName1 and InstanceName2 into one packet

    Packet1 should be like this,

    var packet1 = new Packet
                {
                    Id = new Guid("2e08bd98-68eb-4358-8efb-9f2adedfb034"),
                    Results = new Result
                    {
                        ResultName = "ResultName1",
                        Instances = new List<Instance>
                        {
                            new Instance
                            {
                                InstanceName = "InstanceName1",
                                InstanceDatas = new List<InstanceData>
                                {
                                    new InstanceData{Name = "N1", Value = "V1"},
                                }
                            },
                            new Instance
                            {
                                InstanceName = "InstanceName2",
                                InstanceDatas = new List<InstanceData>
                                {
                                    new InstanceData{Name = "N1", Value = "V3"},
                                }
                            }
                        }
                    }
                };

    and similarly packet2.

    I have tried below, but this will split on InstanceData as well and giving 4 packets. What could be the solution?

    var packets = dataPacket.Results
                    .Instances
                    .SelectMany(x =>
                        x.InstanceDatas.Select(y => new Packet()
                        {
                            Id = dataPacket.Id,
                            Results = new Result()
                            {
                                ResultName = dataPacket.Results.ResultName,
                                Instances = new List<Instance>()
                                {
                                    new Instance()
                                    {
                                        InstanceDatas = new List<InstanceData>() {y},
                                        InstanceName = x.InstanceName
                                    }
                                }
                            }
                        }));


    Friday, September 11, 2020 9:34 AM

All replies

  • Hi,

    you should use groupby the nested object name property, here a SO thread:

    https://stackoverflow.com/questions/9578887/nested-group-by-linq


    Friday, September 11, 2020 1:20 PM
  • Thanks.

    something like this is working, where I first filter out all the "Name" then loop around it and prapare.

    Is there any other better way ?

    IList<string> names = packet.Results.Instances
            .SelectMany(it => it.InstanceDatas)
            .Select(it => it.Name)
            .Distinct()
            .ToList();
        IList<Packet> result = new List<Packet>();
        foreach (string name in names)
        {
            List<Instance> newInstances = packet.Results.Instances
                .Select(it => new Instance {
                    InstanceName = it.InstanceName,
                    InstanceDatas = it.InstanceDatas
                        .Where(it1 => it1.Name == name)
                        .ToList()
                })
                .Where(it => it.InstanceDatas.Any())
                .ToList();
            Result newResult = new Result {
                ResultName = packet.Results.ResultName,
                Instances = newInstances
            };
            result.Add(new Packet {
                Id = packet.Id,
                Results = newResult                    
            });
        }

    Friday, September 11, 2020 3:47 PM
  • Hi Yazdani ISTS,
    First, I am glad you have got your solution,we suggest that you mark it as the answer. So it can help other people who have the same problem find a solution quickly.
    And you can try to use group by LINQ as Cherkaoui said.
    Best Regards,
    Daniel Zhang


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Wednesday, September 16, 2020 7:54 AM