I have array of objects like this
{ title: "A", parent_id: "root",has_children: true}
{ title: "A1", parent_id: "A",has_children: true}
{ title: "A11", parent_id: "A1",has_children: false}
{ title: "A12", parent_id: "A1",has_children: false}
{ title: "A13", parent_id: "A1",has_children: false}
{ title: "B", parent_id: "root",has_children: true}
{ title: "B1", parent_id: "A",has_children: true}
{ title: "B11", parent_id: "B1",has_children: false}
{ title: "B12", parent_id: "B1",has_children: false}
{ title: "B13", parent_id: "B1",has_children: false}
each record has params saying whether it has any children or not and what is the parent for that card.
record with "root" is the top level card.
From the data above I want something like below
[
{
"title": "A",
"children": [
{
"title": "A1",
"children": [
{
"title": "A11"
},
{
"title": "A12"
},
{
"title": "A13."
}
]
},
{
"title": "A2",
"children": [
{
"title": "A21"
},
{
"title": "A22"
},
{
"title": "A23"
}
]
}
]
},
{
"title": "B",
"children": [
{
"title": "B1",
"children": [
{
"title": "B11"
},
{
"title": "B12"
},
{
"title": "B13."
}
]
},
{
"title": "B2",
"children": [
{
"title": "B21"
},
{
"title": "B22"
},
{
"title": "B23"
}
]
}
]
}
]
I'm trying for a while to do this but couldn't do it, here is what I tried
I'm doing this in meteor using mongodb
getUserJSON = function(userId){
var userJSON = [];
getJSONCards(userId,'root', userJSON)
}
getJSONCards = function(userId, parent_id, userData){
var allCards = userCards.find({ $and: [ { user_id: userId }, { parent_id: parent_id } ] }).fetch();
if(allCards.length > 0){
allCards.forEach(function (cardInfo) {
var isExist = $.grep(userData, function(e){ return e.content === parent_id; });
if(isExist){
//here I don't know how to insert nested cards
}
});
}
}
But I'm hoping for simple js solution
The solution below uses the following approach:
title
value from the allCards
collection by using Array.prototype.reduce() . root
items in the collection, while at the same time assign each item as a child to their respective parents if they do exist in the indexed
variable. var allCards = [ { title: "A", parent_id: "root", has_children: true}, { title: "A1", parent_id: "A", has_children: true}, { title: "A11", parent_id: "A1", has_children: false}, { title: "A12", parent_id: "A1", has_children: false}, { title: "A13", parent_id: "A1", has_children: false}, { title: "B", parent_id: "root", has_children: true}, { title: "B1", parent_id: "A", has_children: true}, { title: "B11", parent_id: "B1", has_children: false}, { title: "B12", parent_id: "B1", has_children: false}, { title: "B13", parent_id: "B1", has_children: false} ]; // index each item by title var indexed = allCards.reduce(function(result, item) { result[item.title] = item; return result; }, {}); // retain the root items only var result = allCards.filter(function(item) { // get parent var parent = indexed[item.parent_id]; // make sure to remove unnecessary keys delete item.parent_id; delete item.has_children; // has parent? if(parent) { // add item as a child parent.children = (parent.children || []).concat(item); } // This part determines if the item is a root item or not return !parent; }); document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
Here is one way of doing it. Iterate the array of objects, building a new object for each one and store it in a cache so you can directly modify that object when its children are processed. Parents must appear before children for this to work, otherwise you'd have to build in multiple passes.
// define data array
var data = [
{ title: "A", parent_id: "root",has_children: true},
{ title: "A1", parent_id: "A",has_children: true},
{ title: "A11", parent_id: "A1",has_children: false},
{ title: "A12", parent_id: "A1",has_children: false},
{ title: "A13", parent_id: "A1",has_children: false},
{ title: "B", parent_id: "root",has_children: true},
{ title: "B1", parent_id: "A",has_children: true},
{ title: "B11", parent_id: "B1",has_children: false},
{ title: "B12", parent_id: "B1",has_children: false},
{ title: "B13", parent_id: "B1",has_children: false}
];
var root = {};
var parentCache = {};
// for each element definition in the data array
for (var i = 0; i < data.length; i++) {
var element = data[i];
var title = element.title;
// XXX - check for duplicate title here.
// create a new object and initialize
var newObj = {"title" : title};
if (element.has_children) {
newObj["children"] = [];
}
// put this object into its parent
if (element.parent_id === "root") {
root[title] = newObj;
} else {
// XXX - if the parent isn't defined first this will fail
var parent = parentCache[element.parent_id];
parent.children.push(newObj);
}
// store this object in case it is a parent
parentCache[title] = newObj;
}
console.log(JSON.stringify(root));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.