I will like to know how to joins the parents.json with the childrens.json using JavaScript. I need to get the result.json
First object: parents.json
{
"name": "ParentsLevel2",
"Level": 1,
"children": [
{
"name": "analytics",
"level": 2,
},
{
"name": "animate",
"level": 2
}
]
}
Second object: childrens.json
{
"name": "childrensLevel3",
"Level": 1,
"children": [
{
"name": "analytics1",
"level": 3,
"parent": "analytics"
},
{
"name": "analytics2",
"level": 3,
"parent": "analytics"
},
{
"name": "animate1",
"level": 3,
"parent": "animate"
},
{
"name": "animate2",
"level": 3,
"parent": "animate"
}
]
The result: result.json
{
"name": "Root",
"Level": 1,
"children": [
{
"name": "analytics",
"level": 2,
"children": [
{
"name": "analytics1",
"level": 3
},
{
"name": "analytics2",
"level": 3
}
]
},
{
"name": "animate",
"level": 2
"children": [
{
"name": "animate1",
"level": 3
}
]
}
]
}
I have this:
var parent= parents.json
var child= childrens.json
var obj=parent["children"];
var obj2=child["children"];
for(i in obj){
for(c in obj2){
if(obj[i].name == obj2[c].parent){
//here is the push of the child associated to the parent, but how and
//also how create the result.json I need to create other object to put all together.
}
}
}
try this code
var obj1 = { "name": "ParentsLevel2", "Level": 1, "children": [ { "name": "analytics", "level": 2, }, { "name": "animate", "level": 2 } ]
};
var obj2 = { "name": "childrensLevel3", "Level": 1, "children": [ { "name": "analytics1", "level": 3, "parent": "analytics" }, { "name": "analytics2", "level": 3, "parent": "analytics" }, { "name": "animate1", "level": 3, "parent": "animate" }, { "name": "animate2", "level": 3, "parent": "animate" } ]};
var obj = {};
obj [0] = obj 1;
obj [1] = obj 2;
console.log(obj);
Solution:
var parentJson={
"name": "ParentsLevel2",
"Level": 1,
"children": [
{
"name": "analytics",
"level": 2,
"children":[]
},
{
"name": "animate",
"level": 2,
"children":[]
}
]
};
var sonJson={
"name": "ChildrenLevel3",
"Level": 1,
"children": [
{
"name": "analytics1",
"level": 3,
"parent": "analytics"
},
{
"name": "analytics2",
"level": 3,
"parent": "analytics"
}
]
};
//push a new object to the parentJson
//parentJson["children"].push("object to push");
//push a new object to the sonJson
//sonJson["children"].push("object to push");
//join
var objSon=sonJson["children"];
var oP=parentJson["children"];
for(p in oP){
for(s in objSon){
if(oP[p].name==objSon[s].parent){
alert("match");
oP[p].children.push(objSon[s]);
}
}
}
//create the result
var result=[];
var obj=oP;
for(i in obj){
var temp=[];
temp.push("FirstName");
temp.push(obj[i].name);
temp.push("Level");
temp.push(obj[i].level);
temp.push("Hijos")
temp.push(obj[i].children);
result.push(temp);
$("#D3").html(JSON.stringify(result));
$("#D3").prepend("result=")
jsfiddle Solution
Related
I have nested array like following.
const tree = {
"id": 1,
"name": "mainOrgName",
"children": [
{
"id": 10,
"name": "East Region",
"children": [
{
"id": 11,
"name": "test east sub 1",
"children": [
{
"id": 12,
"name": "sub 22 sub 1",
"children": [
{
"id": 15,
"name": "sub 333 of sub ",
"children": [
{
"id": 16,
"name": "sub 4444",
"children": []
}
]
}
]
}
]
}
]
},
{
"id": 13,
"name": "west region",
"children": [
{
"id": 14,
"name": "test west sub 1",
"children": []
}
]
}
]
}
I need to traverse through tree.children array to get all id and name of sub arrays and its children until we didn't find children array empty. (Note: children array may be empty or may have further levels)
I need result like follows
Expected result
[
{
"name": "East Region",
"value": 10,
"selected": false
},
{
"name": "test east sub 1",
"value": 11,
"selected": false
},
{
"name": "sub 22 sub 1",
"value": 12,
"selected": false
},
{
"name": "sub 333 of sub",
"value": 15,
"selected": false
},
{
"name": "sub 4444",
"value": 16,
"selected": false
},
{
"name": "west region",
"value": 13,
"selected": false
},
{
"name": "test west sub 1",
"value": 14,
"selected": false
},
]
I tried following
const candidates = tree.children.map(org => ({name: org.name, value: org.id, selected: false}));
but it gives me following
[
{
"name": "East Region",
"value": 10,
"selected": false
},
{
"name": "west region",
"value": 13,
"selected": false
}
]
I am trying to get that but not sure how I can put condition that traverse until children is empty and push required fields in final array in required format. May need recursive/call back functions but not sure how I can use that.
Please help to get expected result. Thanks
Try this,
const tree = {
"id": 1,
"name": "mainOrgName",
"children": [
{
"id": 10,
"name": "East Region",
"children": [{
"id": 11,
"name": "test east sub 1",
"children": [{
"id": 12,
"name": "sub 22 sub 1",
"children": [{
"id": 15,
"name": "sub 333 of sub ",
"children": [{
"id": 16,
"name": "sub 4444",
"children": []
}]
}]
}]
}]
},
{
"id": 13,
"name": "west region",
"children": [{
"id": 14,
"name": "test west sub 1",
"children": []
}]
}
]
}
let items = []
let result = lootIt(tree.children)
console.log(result)
function lootIt (arr) {
for(let i = 0 ; i< arr.length ; i++){
let obj = {}
obj['name'] = arr[i]['name']
obj['value'] = arr[i]['id']
obj['selected'] = false
items.push(obj)
if(arr[i].children !== 0){
lootIt(arr[i].children)
}
}
return items
}
You can use recursion to do it
const tree = {
"id": 1,
"name": "mainOrgName",
"children": [
{
"id": 10,
"name": "East Region",
"children": [
{
"id": 11,
"name": "test east sub 1",
"children": [
{
"id": 12,
"name": "sub 22 sub 1",
"children": [
{
"id": 15,
"name": "sub 333 of sub ",
"children": [
{
"id": 16,
"name": "sub 4444",
"children": []
}
]
}
]
}
]
}
]
},
{
"id": 13,
"name": "west region",
"children": [
{
"id": 14,
"name": "test west sub 1",
"children": []
}
]
}
]
}
function mapTree(children){
let result =[]
for(c of children){
result.push({name: c.name, value: c.id, selected: false})
result = result.concat(mapTree(c.children))
}
return result
}
console.log(mapTree(tree.children))
BE Response:- which I am getting from Backend Service
{
"data": {
"type": "AnyType",
"resources": [
{
"id": 1,
"treeId": "1",
"name": "name1",
"description": "description1",
"children": [
{
"id": 3,
"treeId": "1-3",
"name": "subName1",
"description": "subDescription1",
"children": [
{
"id": 6,
"treeId": "1-3-6",
"name": "subSubName1",
"description": "subSubDesc1",
"children": []
}
]
}
]
},
{
"id": 2,
"treeId": "2",
"name": "name2",
"description": "description2",
"children": [
{
"id": 7,
"treeId": "2-7",
"name": "subName2",
"description": "subDescription2",
"children": []
}
]
}
]
}
}
But I need to modify this response to as below on FE
Expected Response:- means I need to join name and description field text to one(in name field ) as below:-
{
"data": {
"type": "AnyType",
"resources": [
{
"id": 1,
"treeId": "1",
"name": "name1-description1",
"description": "description1",
"children": [
{
"id": 3,
"treeId": "1-3",
"name": "subName1-subDescription1",
"description": "subDescription1",
"children": [
{
"id": 6,
"treeId": "1-3-6",
"name": "subSubName1-subSubDesc1",
"description": "subSubDesc1",
"children": []
}
]
}
]
},
{
"id": 2,
"treeId": "2",
"name": "name2-description2",
"description": "description2",
"children": [
{
"id": 7,
"treeId": "2-7",
"name": "subName2-subDescription2",
"description": "subDescription2",
"children": []
}
]
}
]
}
}
there could be n number of children of each object and children can have an array of objects.
What I have done:- I am able to change the very first name but not children name
let resDataArry = [];
let descData: DynamicResource;
response.forEach((x, index) => {
const descName = x.name + ' ' + x.description;
descData = { ...tree.resources[index], name: descName };
resDataArry.push(descData);
});
return resDataArry;
Please help.
You can use nested Array#forEach to access children array and then concatenate the name and description together.
let data = {
"data": {
"type": "AnyType",
"resources": [
{
"id": 1,
"treeId": "1",
"name": "name1",
"description": "description1",
"children": [
{
"id": 3,
"treeId": "1-3",
"name": "subName1",
"description": "subDescription1",
"children": [
{
"id": 6,
"treeId": "1-3-6",
"name": "subSubName1",
"description": "subSubDesc1",
"children": []
}
]
}
]
},
{
"id": 2,
"treeId": "2",
"name": "name2",
"description": "description2",
"children": [
{
"id": 7,
"treeId": "2-7",
"name": "subName2",
"description": "subDescription2",
"children": []
}
]
}
]
}
}
data.data.resources.forEach(function(item){
item.name = item.name + ' ' + item.description;
item.children.forEach(function(child){
child.name = child.name + ' ' + child.description;
});
});
console.log(data);
I have an array of data like this one
[
{
"id": "root_01",
"parents": [
{
"id": "parent_1",
"childrens": [
{
"id": "child_01",
"name": "ABC",
"group": "group_a"
},
{
"id": "child_02",
"name": "BBC",
"group": "group_b"
}
]
},
{
"id": "parent_2",
"childrens": [
{
"id": "child_03",
"name": "CCD",
"group": "group_a"
},
{
"id": "child_04",
"name": "EEF",
"group": "group_c"
}
]
}
]
},
{} // same as previous
]
and I'm trying to get rid of all parents data & catch & merge only child items like this one:
[
{
"id": "child_01",
"name": "ABC",
"group": "group_a"
},
{
"id": "child_02",
"name": "BBC",
"group": "group_b"
},
{
"id": "child_03",
"name": "CCD",
"group": "group_a"
},
{
"id": "child_04",
"name": "EEF",
"group": "group_c"
}
]
but after reading normalizr documentation I'm a little bit confused because I couldn't find this kind of example, so can anyone suggest me is it possible to make with normalizr or any better idea?
Thanks
Recusrion is what you need here:
const arr = [ { "id": "root_01", "parents": [ { "id": "parent_1", "childrens": [ { "id": "child_01", "name": "ABC", "group": "group_a" }, { "id": "child_02", "name": "BBC", "group": "group_b" } ] }, { "id": "parent_2", "childrens": [ { "id": "child_03", "name": "CCD", "group": "group_a" }, { "id": "child_04", "name": "EEF", "group": "group_c" } ] } ] }];
const flatten = arr => arr.flatMap(o=>o.parents ? flatten(o.parents) : o.childrens ? flatten(o.childrens) : o);
console.log(flatten(arr));
I need to convert below unformatted JSON format into formatted input. We need to find id's similar to parent id for different items inside array element of object and then need to push it into children to that id. Below is my code that needs to transform
Input
{
"0": [
{
"id": 10,
"title": "House",
"level": 0,
"children": [],
"parent_id": null
}
],
"1": [
{
"id": 12,
"title": "Red Roof",
"level": 1,
"children": [],
"parent_id": 10
},
{
"id": 18,
"title": "Blue Roof",
"level": 1,
"children": [],
"parent_id": 10
}
],
"2": [
{
"id": 17,
"title": "Blue Windoww",
"level": 2,
"children": [],
"parent_id": 12
},
{
"id": 16,
"title": "Door",
"level": 2,
"children": [],
"parent_id": 13
}
]
}
Output
[
{
"id": 10,
"title": "House",
"level": 0,
"children": [
{
"id": 12,
"title": "RedRoofff",
"level": 1,
"children": [
{
"id": 17,
"title": "Blue Windoww",
"level": 2,
"children": [],
"parent_id": 12
}
],
"parent_id": 10
},
{
"id": 18,
"title": "Blue Roof",
"level": 1,
"children": [],
"parent_id": 10
},
{
"id": 13,
"title": "Wall",
"level": 1,
"children": [
{
"id": 16,
"title": "Door",
"level": 2,
"children": [],
"parent_id": 13
}
],
"parent_id": 10
}
],
"parent_id": null
}
]
Please find the solution to above problem.
first, we track the node with Id and then we update the children array like this.
(btw, your input have a missing node, 13)
const input = {
"0": [{
"id": 10,
"title": "House",
"level": 0,
"children": [],
"parent_id": null
}, {
"id": 13,
"title": "Wall",
"level": 0,
"children": [],
"parent_id": null
}],
"1": [{
"id": 12,
"title": "Red Roof",
"level": 1,
"children": [],
"parent_id": 10
},
{
"id": 18,
"title": "Blue Roof",
"level": 1,
"children": [],
"parent_id": 10
},
],
"2": [{
"id": 17,
"title": "Blue Windoww",
"level": 2,
"children": [],
"parent_id": 12
},
{
"id": 16,
"title": "Door",
"level": 2,
"children": [],
"parent_id": 13
},
]
};
const results = [];
const mapId2Node = Object.values(input).reduce((acc, vals) => {
vals.forEach(val => {
acc[val.id] = val;
if (val.parent_id === null) {
results.push(val);
}
});
return acc;
}, {});
Object.values(input).forEach(vals => {
vals.forEach(val => {
if (val.parent_id !== null) {
mapId2Node[val.parent_id].children.push(val);
}
});
});
conosle.log(results);
I have two variables array1 and array2 as following and I want to put the values of array2 into array1 for the properties present in array1 and rest of the properties should remain the same with default values.
One solution I have is to iterate through the array length and set values for found properties and but my array is too long to perform iteration (the array supplied in this question is just a raw value).
I need some better way other than iteration.
var array1=[
{
"name": "a",
"value": 0,
"level": [
{
"name": "a1",
"value": 0
},
{
"name": "a2",
"value": 0
}
]
},
{
"name": "b",
"value": 0,
"level": [
{
"name": "b1",
"value": 0
},
{
"name": "b2",
"value": 0
}
]
},
{
"name": "c",
"value": 0,
"level": [
{
"name": "c1",
"value": 0
},
{
"name": "c2",
"value": 0
}
]
}
]
var array2=[
{
"name": "a",
"value": 1,
"level": [
{
"name": "a1",
"value": 1
},
{
"name": "a2",
"value": 0
}
]
},
{
"name": "b",
"value": 1,
"level": [
{
"name": "b1",
"value": 0
},
{
"name": "b2",
"value": 1
}
]
}
]
and the required output is
var final_array=[
{
"name": "a",
"value": 1,
"level": [
{
"name": "a1",
"value": 1
},
{
"name": "a2",
"value": 0
}
]
},
{
"name": "b",
"value": 1,
"level": [
{
"name": "b1",
"value": 0
},
{
"name": "b2",
"value": 1
}
]
},
{
"name": "c",
"value": 0,
"level": [
{
"name": "c1",
"value": 0
},
{
"name": "c2",
"value": 0
}
]
}
]
A recursive solution with two iterators, one for arrays iterateA and one for objects iterateO. This proposal uses the thisArg for reference to json2.
Basically both callbacks iterates over the items or keys and checks if this is set and if the actual item is present in this. if not, the function returns.
The rest is straight forward, if an object is found, then it iterates over the keys and the object, if an array is found, the it it iterates over the array.
Only in the case of k === 'value' the value of this[k] is to o[k] assigned.
var json1 = [{ "name": "a", "value": 0, "level": [{ "name": "a1", "value": 0 }, { "name": "a2", "value": 0 }] }, { "name": "b", "value": 0, "level": [{ "name": "b1", "value": 0 }, { "name": "b2", "value": 0 }] }, { "name": "c", "value": 0, "level": [{ "name": "c1", "value": 0 }, { "name": "c2", "value": 0 }] }],
json2 = [{ "name": "a", "value": 1, "level": [{ "name": "a1", "value": 1 }, { "name": "a2", "value": 0 }] }, { "name": "b", "value": 1, "level": [{ "name": "b1", "value": 0 }, { "name": "b2", "value": 1 }] }];
function iterateO(o) {
return function (k) {
if (!this || !(k in this)) {
return;
}
if (typeof o[k] === 'object') {
Object.keys(o[k]).forEach(iterateO(o[k]), this[k]);
return;
}
if (Array.isArray(o[k])) {
o[k].forEach(iterateA, this[k]);
return;
}
if (k === 'value') {
o[k] = this[k];
}
};
}
function iterateA(a, i, aa) {
if (!this || !(i in this)) {
return;
}
if (typeof a === 'object') {
Object.keys(a).forEach(iterateO(a), this[i]);
return;
}
if (Array.isArray(a)) {
a.forEach(iterateA, this[i]);
return;
}
}
json1.forEach(iterateA, json2);
document.write('<pre>' + JSON.stringify(json1, 0, 4) + '</pre>');