0

I cannot get my recursion to work again :/

I have a list that contains some self-referential items but how can I put them in a list of lists if they belong together based on their keys.

Can somebody help me with this issue? Please :)

Here is some code.

public class Employees
{
    public int employeeID { get; set; }
    public int? parentEmployeeID { get; set; }
    public string Name { get; set; }
    public string Position { get; set; }
}
    List<Employees> Employeelist = new List<Employees> {
new Employees { employeeID = 1, parentEmployeeID = null, Name = "Mike", Position = "CIO" },
new Employees { employeeID = 2, parentEmployeeID = 1, Name = "Robs", Position = "Sales" },
new Employees { employeeID = 3, parentEmployeeID = 7, Name = "Fred", Position = "Manager" },
new Employees { employeeID = 4, parentEmployeeID = 6, Name = "Pablo", Position = "Economy" },
new Employees { employeeID = 5, parentEmployeeID = 2, Name = "Erica", Position = "Sometingelse" },
new Employees { employeeID = 6, parentEmployeeID = null, Name = "Obama", Position = "" },
new Employees { employeeID = 7, parentEmployeeID = 5, Name = "Brad", Position = "" },
new Employees { employeeID = 8, parentEmployeeID = 3, Name = "Amy", Position = "" },
new Employees { employeeID = 9, parentEmployeeID = 4, Name = "Howard", Position = "" },
};

    List<List<Employees>> StrucutedEmployeeList = new List<List<Employees>>();
    private void ArrangeInNewlistofLists(Employees root, int? parentOptionID)
    {
        foreach (Employees option in Employeelist.Where(x => x.employeeID == parentOptionID))
        {
            List<Employees> temp = new List<Employees>();
            StrucutedEmployeeList.Add(temp);
            ArrangeInNewlistofLists(option, option.parentEmployeeID);
        }
    }

    public void ArrangeListWithRecursion()
    {
        foreach (var item in Employeelist)
        {
            if (item.parentEmployeeID == null)
                ArrangeInNewlistofLists(item, null);
        }

    }
John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Dec 17 '12 at 19:46

3 Answers3

0

First of all: foreach (Employees option in Employeelist.Where(x => x.employeeID == parentOptionID)) - This will never return any results since you have no Employee who's ID is null...

I think you want x.parentEmployeeID e.g.

foreach (Employees option in Employeelist.Where(x => x.parentEmployeeID == parentOptionID))

Also, this makes no since:

List<Employees> temp = new List<Employees>();
StrucutedEmployeeList.Add(temp);

You're always adding empty lists and not doing anything else with them...

This should do what you want:

public class Employees
{
    public int employeeID { get; set; }
    public int? parentEmployeeID { get; set; }
    public string Name { get; set; }
    public string Position { get; set; }

    public List<Employees> subEmp { get; set; }
}

Notice you have the subEmp list. Now to populate call ArrangeListWithRecursion():

    List<Employees> StrucutedEmployeeList = new List<Employees>();
    private Employees ArrangeInNewlistofLists(Employees item, int? parentOptionID)
    {
        item.subEmp = new List<Employees>();

        foreach (Employees option in Employeelist.Where(x => x.parentEmployeeID == parentOptionID))
        {
            item.subEmp.Add(ArrangeInNewlistofLists(option, item.employeeID));
        }
        return item;
    }

    public void ArrangeListWithRecursion()
    {
        foreach (var item in Employeelist.Where(x=>x.parentEmployeeID == null))
        {
            StrucutedEmployeeList.Add(ArrangeInNewlistofLists(item, item.employeeID));
        }

    }
Blachshma
  • 17,097
  • 4
  • 58
  • 72
0

The way you are structuring the code won't allow for a truly recursive solution. By adding the children property to Employees you will get the solution you want.

        public class Employees
        {
            public int employeeID { get; set; }
            public int? parentEmployeeID { get; set; }
            public string Name { get; set; }
            public string Position { get; set; }

            public List<Employees> Children { get; set; }
        }


        public void Arrange()
        {
            Employeelist = ArrangeListWithRecursion();
        }

        private List<Employees> ArrangeListWithRecursion(int? parentId = null)
        {
            var result = new List<Employees>();
            foreach (var employee in Employeelist.Where(e => e.parentEmployeeID == parentId))
            {
                var children = Employeelist.Where(e => e.parentEmployeeID == employee.employeeID).ToList();
                employee.Children = ArrangeListWithRecursion(employee.employeeID);
                result.Add(employee);
            }
            return result;
        }
Joel Kravets
  • 2,473
  • 19
  • 16
0

I'm not quite sure what you are trying to accomplish with your example. Assuming you are trying to group your related employees together, one approach could be to reorganize your objects like the this:

Employees class:

public class Employees : List<Employee>
{
    public new void Add(Employee employee)
    {
        employee.employees = this;
        base.Add(employee);
    }
}

Employee class:

public class Employee
{
    public Employees employees { get; set; }
    public int employeeID { get; set; }
    public int? parentEmployeeID { get; set; }
    public string Name { get; set; }
    public string Position { get; set; }

    public Employee Boss 
    {
        get 
        {
            return employees.FirstOrDefault(e => e.employeeID == this.parentEmployeeID); 
        }
    }

    public IEnumerable<Employee> Subordinates 
    { 
        get
        {
            return employees.Where(e => e.parentEmployeeID == this.employeeID);
        }
    }
}

Populating the employees:

var employees = new Employees();
employees.Add(new Employee { employeeID = 1, parentEmployeeID = null, Name = "Mike", Position = "CIO" });
employees.Add(new Employee { employeeID = 2, parentEmployeeID = 1, Name = "Robs", Position = "Sales" });
employees.Add(new Employee { employeeID = 3, parentEmployeeID = 7, Name = "Fred", Position = "Manager" });
employees.Add(new Employee { employeeID = 4, parentEmployeeID = 6, Name = "Pablo", Position = "Economy" });
employees.Add(new Employee { employeeID = 5, parentEmployeeID = 2, Name = "Erica", Position = "Sometingelse" });
employees.Add(new Employee { employeeID = 6, parentEmployeeID = null, Name = "Obama", Position = "" });
employees.Add(new Employee { employeeID = 7, parentEmployeeID = 5, Name = "Brad", Position = "" });
employees.Add(new Employee { employeeID = 8, parentEmployeeID = 2, Name = "Amy", Position = "" });
employees.Add(new Employee { employeeID = 9, parentEmployeeID = 2, Name = "Howard", Position = "" });

This allows you to populate only a single list of employees and from there you can get each employee's Boss or their Subordinates using the property on the individual Employee object.

Jason Whitted
  • 4,059
  • 1
  • 16
  • 16
  • I can really change the structure of the class where i get the employees, but lets say i want to count how many children thats under Mike that have null is that possible? – user1374734 Dec 18 '12 at 17:34
  • I'm confused about your question. In order for employees to be children of mike they must have their parentEmployeeID set to Mike's employeeID and not null. – Jason Whitted Dec 18 '12 at 19:25