LADransfield LADransfield - 6 months ago 10
JSON Question

Appending entries into a nested array

Essentially, I' trying to end up with an array that looks like this:

{
"projects" : [{
"project" : "Project One",
"tasks" : [{
"name" : "Task One"
}, {
"name" : "Task Two"
}, {
"name" : "Task Three"
}]
}, {
"project" : "Project Two",
"tasks" : [{
"name" : "Task One"
}, {
"name" : "Task Two"
}]
}]
}


I currently have the following array and a script which look at each element of tasks and checks to see that it's not already in a list of project names, then inserts the first one if it's not, and should add a second element if it is, but that's where I'm a little stuck:



var tasks = [{
"name" : "Task One",
"project" : "Project One"
}, {
"name" : "Task One",
"project" : "Project Two"
}, {
"name" : "Task Two",
"project" : "Project One"
}, {
"name" : "Task Three",
"project" : "Project One"
}, {
"name" : "Task Two",
"project" : "Project Two"
}]


var projectNames = [];
var projects = [];
for ( i = 0; i < tasks.length; i++) {
if (projectNames.indexOf(tasks[i].project) < 0) {
// checks to see that it's not the projectNames list, and inserts the first entry
projectNames.push(tasks[i].project);
projects.push({
project : tasks[i].project,
tasks : {
name : tasks[i].name
}
});
} else {
// if that project is already in the list, append the next entry
var ind = projectNames.indexOf(tasks[i].project);
projects[ind].tasks.push({
name : tasks[i].name
});
}
}





I'm under the impression that
projects[ind].tasks.push()
can't be used, but I'm not sure what the correct thing to replace it with would be?

(Equally if there are any better methods of getting from the first array to the second, I'm always happy to learn something new)

Answer

Your problem is here:

projects.push({ project: tasks[i].project, tasks: { name: tasks[i].name } });

You are adding tasks as an object, not an array. You should add it as an array with the object as its sole element:

projects.push({ project: tasks[i].project, tasks: [{ name: tasks[i].name }[ });