# Looping through nested arrays with creating new array from nested items

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.

• 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? Aug 28 '15 at 17:27
• @jfriend00 I have edited OP, data is structured to go 2 levels deep with nested arrays. Aug 28 '15 at 17:35
• 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?
– Dan
Aug 28 '15 at 17:37
• @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. Aug 28 '15 at 17:39

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