locked
Linq with nested lists RRS feed

  • Question

  • User369345748 posted

    I have an organisation structure in a query object called Retval , whos structure I am trying to flatten with linq so that I can get a person's name, id & their manager

    This is the the source

    Name A,ID 0
    Team
    [
     Name B,ID 1
     Team[],
     Name C,ID 2
     Team
          [Name E,ID 3
       Team[]
    ]]

    This is parsed into an object structure 

    public class Rootobject

    public Child[] Team{ get; set; }

    public Li_Attr li_attr { get; set; }

     public string Name{ get; set; }

    }

    public class Li_Attr{

    public string ID { get; set; }

    }

    public class Child
    {
         public Child1[] Team{ get; set; }
         public Li_Attr li_attr { get; set; }
         public string Name{ get; set; }
    }

     public class Child1{
    public object[] Team{ get; set; }
    public Li_Attr li_attr { get; set; }
    public string Name{ get; set; }
    }

    I am trying to get to a flattened structure showing who they report to directly 

    Id 3, Name E, Reports 2
    Id 2, Name C, Reports 0
    Id 1, Name B, Reports 0
    Id 0, Name A, Reports null

    var one  = retval.children.SelectMany(b => b.children.SelectMany(c => c.children    .Select(p => b.text + ", " + c.text + ", " + c.text)));

    var two  = retval.children.SelectMany(a => a.children).ToList();

    var three = retval.children.SelectMany(a => a.children.ToList()).ToList();

    var four  =  retval.children.SelectMany(a => a.children.ToList().SelectMany(b => b.children).ToList()).ToList();

    var one does not return anything even though that was my start point for getting data out

    var two  returns a number of rows, but doesn't populate the children object

    var three does populate the nested children object

    var four returns no rows

    Any suggestions gratefully received

    Tuesday, September 10, 2019 3:58 PM

Answers

  • User665608656 posted

    Hi Richard,

    According to your description,  your Retval structure is complex.

    If you use linq to implement the format you need to display, it will be very difficult, so I suggest that you create a new class to store the format you need to see, and make circular judgments about Retval.

    I have made the data as your provided, for more details , you could refer to the following code:

    Create a new class named NewRoot:

        public class NewRoot
        {
            public string Id { get; set; }
            public string Name { get; set; }
            public int? Reports { get; set; }
        }
                List<Li_Attr> li_Attrs = new List<Li_Attr>() { new Li_Attr { ID = "1" }, new Li_Attr { ID = "2" }, new Li_Attr { ID = "3" } };
                Child1[] child1s = { new Child1 { li_attr = li_Attrs[2], Name = "E", Team = new string[] { } } };
                Child[] childs = { new Child {  li_attr = li_Attrs[0], Name  = "B", Team =new Child1[] { } },
                    new Child { li_attr = li_Attrs[1], Name = "C", Team = child1s  }};
                Rootobject[] retval = new Rootobject[] { new Rootobject { li_attr = new Li_Attr { ID = "0" }, Name = "A", Team = childs } };
                
    List<NewRoot> newRoots = new List<NewRoot>(); foreach (var item in retval) { NewRoot newRoot1 = new NewRoot(); newRoot1.Id = item.li_attr.ID.ToString(); newRoot1.Name = item.Name.ToString(); newRoot1.Reports = null; newRoots.Add(newRoot1); if (item.Team.Count() > 0) { foreach (var item1 in item.Team) { NewRoot newRoot2 = new NewRoot(); newRoot2.Id = item1.li_attr.ID.ToString(); newRoot2.Name = item1.Name.ToString(); newRoot2.Reports = 0; newRoots.Add(newRoot2); if (item1.Team.Count() > 0) { foreach (var item2 in item1.Team) { NewRoot newRoot3 = new NewRoot(); newRoot3.Id = item2.li_attr.ID.ToString(); newRoot3.Name = item2.Name.ToString(); newRoot3.Reports = 2; newRoots.Add(newRoot3); } } } } } }

    Here is the result of newRoots, which is what you want to get:

    Best Regards,

    YongQing.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 11, 2019 2:57 AM

All replies

  • User665608656 posted

    Hi Richard,

    According to your description,  your Retval structure is complex.

    If you use linq to implement the format you need to display, it will be very difficult, so I suggest that you create a new class to store the format you need to see, and make circular judgments about Retval.

    I have made the data as your provided, for more details , you could refer to the following code:

    Create a new class named NewRoot:

        public class NewRoot
        {
            public string Id { get; set; }
            public string Name { get; set; }
            public int? Reports { get; set; }
        }
                List<Li_Attr> li_Attrs = new List<Li_Attr>() { new Li_Attr { ID = "1" }, new Li_Attr { ID = "2" }, new Li_Attr { ID = "3" } };
                Child1[] child1s = { new Child1 { li_attr = li_Attrs[2], Name = "E", Team = new string[] { } } };
                Child[] childs = { new Child {  li_attr = li_Attrs[0], Name  = "B", Team =new Child1[] { } },
                    new Child { li_attr = li_Attrs[1], Name = "C", Team = child1s  }};
                Rootobject[] retval = new Rootobject[] { new Rootobject { li_attr = new Li_Attr { ID = "0" }, Name = "A", Team = childs } };
                
    List<NewRoot> newRoots = new List<NewRoot>(); foreach (var item in retval) { NewRoot newRoot1 = new NewRoot(); newRoot1.Id = item.li_attr.ID.ToString(); newRoot1.Name = item.Name.ToString(); newRoot1.Reports = null; newRoots.Add(newRoot1); if (item.Team.Count() > 0) { foreach (var item1 in item.Team) { NewRoot newRoot2 = new NewRoot(); newRoot2.Id = item1.li_attr.ID.ToString(); newRoot2.Name = item1.Name.ToString(); newRoot2.Reports = 0; newRoots.Add(newRoot2); if (item1.Team.Count() > 0) { foreach (var item2 in item1.Team) { NewRoot newRoot3 = new NewRoot(); newRoot3.Id = item2.li_attr.ID.ToString(); newRoot3.Name = item2.Name.ToString(); newRoot3.Reports = 2; newRoots.Add(newRoot3); } } } } } }

    Here is the result of newRoots, which is what you want to get:

    Best Regards,

    YongQing.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 11, 2019 2:57 AM
  • User369345748 posted

    Hi Yongqing

    Thank you for replying with such a detailed & helpful response !    I was coming to the same conclusion myself. 

    Thanks again

    Wednesday, September 11, 2019 8:44 AM