3
\$\begingroup\$

I have written this function but I am not so proud on it. I could use some help refactoring it.

Would recursion improve my code?

Data sample.

{  
  "Name":"test2",
  "DepartmentUnitId":"test",
  "ParentDepartmentUnitId":"test",
  "NestedDepartments":[  
    {  
      "Name":"test2",
      "DepartmentUnitId":"test",
      "ParentDepartmentUnitId":"test",
      "NestedDepartments":[]
    },
    {  
      "Name":"test2",
      "DepartmentUnitId":"test",
      "ParentDepartmentUnitId":"test",
      "NestedDepartments":[]
    }
  ]
}

JS:

function indentDepartments(departments, model) {
    var indentedDepartments = [];

    _.each(departments, function (department) {
        indentedDepartments.push(buildDepartment(department, 0));
        _.each(department.NestedDepartments, function (lv1Department) {
            indentedDepartments.push(buildDepartment(lv1Department, 1));
            _.each(lv1Department.NestedDepartments, function (lv2Department) {
                indentedDepartments.push(buildDepartment(lv2Department, 2));
            });
        });
    });

    function buildDepartment(data, level) {
        department = _.pick(data, 'DepartmentUnitId', 'ParentDepartmentUnitId');
        name = _.times(level, function () { return '-'; }).join('') + data.Name;

        _.extend(department, { Name: name });
        return department;
    }
    model.parentDepartments(indentedDepartments);
}

Edit: Nested array can go 2 levels deep, but I wouldn't mind making this function more scalable.

\$\endgroup\$
4
  • \$\begingroup\$ Please show a sample of the data structure you are iterating. Also, is there a limit to how deep you want to iterate or do you just want to keep going as long as there are NestedDepartments? \$\endgroup\$
    – jfriend00
    Aug 28 '15 at 17:27
  • \$\begingroup\$ @jfriend00 I have edited OP, data is structured to go 2 levels deep with nested arrays. \$\endgroup\$
    – neowinian
    Aug 28 '15 at 17:35
  • \$\begingroup\$ Could you explain what your function is meant to do (in a bit more detail, your title is slightly vague) or provide a test case? \$\endgroup\$
    – Dan
    Aug 28 '15 at 17:37
  • \$\begingroup\$ @DanPantry sorry for confusion I thought I explained it good :) Function is accepting array and each item of the array potentially can have nested array. I want to flatten those arrays but to specify on which level of hierarchy the element is added. \$\endgroup\$
    – neowinian
    Aug 28 '15 at 17:39
1
\$\begingroup\$

You could indeed create a recursive function to collect each level of departments, keeping going as long as there are nested departments:

function indentDepartments(departments, model) {

    model.parentDepartments(doIndentDepartments(departments, 0));

    // called recursively to indent each level of department
    function doIndentDepartments(departments, level) {
        // indent departments at current level
        var departments = _.map(departments, function(department) {
            return buildDepartment(department, level);
        });

        // indent nested departments
        if (typeof departments.NestedDepartments != 'undefined') {
            departments.push.apply(departments, doIndentDepartments(departments.NestedDepartments, level +1));
        }

        return departments;
    }

    function buildDepartment(data, level) {
        department = _.pick(data, 'DepartmentUnitId', 'ParentDepartmentUnitId');
        name = _.times(level, function () { return '-'; }).join('') + data.Name;

        _.extend(department, { Name: name });
        return department;
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.