Unexpected data sorting result after filtering from parent and child node - javascript

I have list of tree node metadataList Like below:
[
{
"data": {
"metadata": {
"category": [
"Csp"
]
}
},
"children": [
{
"data": {
"metadata": {
"category": [
"Csp"
]
}
},
"children": [
]
},
{
"data": {
"metadata": {
"category": [
"Mpn"
]
}
},
"children": [
]
},
{
"data": {
"metadata": {
"category": [
"Mpn"
]
}
},
"children": [
]
},
{
"data": {
"metadata": {
"category": [
"Mpn"
]
}
},
"children": [
]
}
]
},
{
"data": {
"metadata": {
"category": [
"Isv"
]
}
},
"children": [
{
"data": {
"metadata": {
"category": [
"Isv"
]
}
},
"children": [
]
},
{
"data": {
"metadata": {
"category": [
"Isv"
]
}
},
"children": [
]
}
]
},
{
"data": {
"metadata": {
"category": [
"Csp"
]
}
},
"children": [
{
"data": {
"metadata": {
"category": [
"Csp"
]
}
},
"children": [
]
}
]
},
{
"data": {
"metadata": {
"category": [
"Mpn"
]
}
},
"children": [
{
"data": {
"metadata": {
"category": [
"Mpn"
]
}
},
"children": [
]
},
{
"data": {
"metadata": {
"category": [
"Mpn"
]
}
},
"children": [
]
},
{
"data": {
"metadata": {
"category": [
"Mpn"
]
}
},
"children": [
]
},
{
"data": {
"metadata": {
"category": [
"Csp"
]
}
},
"children": [
]
},
{
"data": {
"metadata": {
"category": [
"Isv"
]
}
},
"children": [
]
}
]
},
{
"data": {
"metadata": {
"category": [
"Incentives"
]
}
},
"children": [
{
"data": {
"metadata": {
"category": [
"Incentives"
]
}
},
"children": [
]
}
]
}
]
Which is a type of array of data and children collection it's class like below:
export default class CurrentTopicMetadataTreeNode {
public data: CurrentTopicMetadata;
public children: CurrentTopicMetadataTreeNode[];
}
export default class CurrentTopicMetadata {
public id: string;
public metadata: TopicMetadata
}
export class TopicMetadata {
public category: Category[]
}
export enum Category {
Csp = 'Csp',
Mpn = 'Mpn',
Incentives = 'Incentives',
Referrals = 'Referrals',
Isv = 'Isv',
}
What I am trying, to filter list as data and children order as per category. Let say if filter by a category all data and children belongs to that category should come like below order.
But I am getting data like this order :
One Element On Array Problem Set:
Here in this array if I search with Csp Only data in root node which is Csp and data in children only has one data which contains Csp would be in array.
[{
"data": {
"metadata": {
"category": [
"Csp"
]
}
},
"children": [
{
"data": {
"metadata": {
"category": [
"Csp"
]
}
},
"children": [
]
},
{
"data": {
"metadata": {
"category": [
"Mpn"
]
}
},
"children": [
]
},
{
"data": {
"metadata": {
"category": [
"Mpn"
]
}
},
"children": [
]
},
{
"data": {
"metadata": {
"category": [
"Mpn"
]
}
},
"children": [
]
}
]
}]
Expected Output: So after filtered by Csp node should be look like this:
[
{
"data": {
"metadata": {
"category": [
"Csp"
]
}
},
"children": [
{
"data": {
"metadata": {
"category": [
"Csp"
]
}
},
"children": [
]
}
]
}
]
here is my code, where I am doing wrong?
// Rule 1 check parent metadata category whether be empty
// Rule 2 and 3
function find_in_children(children, parent_category) {
children_has_same_category = []
for(var i in children) {
let child = children[i];
if(child.children != undefined && child.children.length > 0 && child.data.metadata.category == parent_category) {
children_has_same_category.push(child);
}
}
if(children_has_same_category.length > 0) {
return children_has_same_category
} else {
for(var i in children) {
let child = children[i];
return find_in_children(child.children, parent_category);
}
}
}
function check_object(object) {
let parent_category = object.data.metadata.category[0];
if(object.children != undefined && object.children.length > 0) {
return {'data': object.data, 'children': find_in_children(object.children, parent_category)}
} else {
return {'data': object.data}
}
}
function apply_rules(object) {
// Rule 1 check parent metadata category whether be empty
if(object.data.metadata.category.length > 0) {
return {'data': object.data}
} else {
return check_object(object)
}
}
target = {
value: 'Isv'
}
filtered_datas = []
for(var i in datas) {
let data = datas[i];
if(data.data.metadata.category.length > 0) {
result = apply_rules(data)
if(result.data.metadata.category[0] == target.value) {
filtered_datas.push(result);
}
}
}
Here is the data sample and result: https://jsfiddle.net/faridkiron/b02cksL8/#&togetherjs=F7FK3fBULx

I have resolve above problem like below way:
const findMatchedChild = (nodeInList, type) => {
const node = Object.assign({}, nodeInList)
node.children = nodeInList.children
.filter(child => child.data.metadata.category.includes(type))
.map(child => findMatchedChild(child, type))
return node
}
const cspList = findMatchedChild({ children: data }, 'Csp').children
console.log(JSON.stringify(cspList, null, 2));
Got the expected result.

Related

How to check if array is empty or not and return value inside foreach in angular8

I have below data,
What i want to do is, i need to check values[] array in each object,
if it is empty then return true, else if values[] array has some record, it will return false.
i have created function for this, but it is reuturning false everytime.
if it is true thn i want to hide table. Table are multiple not single one, so if values arrayis empty thn only want to hide particular table.
{
"records": [
{
"context": {
"team": [
"MYTEAM-Consume-TEAM-SETUP-ADMIN"
]
},
"values": []
},
{
"context": {
"team": [
"TEAM1"
]
},
"values": [
{
"value": "red",
"label": "dd"
}
]
},
{
"context": {
"team": [
"Test"
]
},
"values": []
},
]
}
Code
hideContextTable(rows) {
const data = rows;
if (data.records) {
data.records.forEach(function (record) {
if (record.values.length === 0) {
return true;
}
});
}
return false;
}
deleteAllContextData(data) {
const tbl = this.hideContextTable(data);
console.log(tbl,"tbl");
if (tbl) {
this.showContextTables = false;
}
}
Simply check the length of returned data from filter function.
data = {
"records": [
{
"context": {
"team": [
"MYTEAM-Consume-TEAM-SETUP-ADMIN"
]
},
"values": []
},
{
"context": {
"team": [
"TEAM1"
]
},
"values": [
{
"value": "red",
"label": "dd"
}
]
},
{
"context": {
"team": [
"Test"
]
},
"values": []
},
]
};
function hideContextTable(data) {
const result = data.records.filter(record => record.values.length);
const flag = result.length ? true : false;
console.log(flag)
}
hideContextTable(data);
return in the higher order function of forEach will not cause flow to leave the hideContextTable function. You should use a variable that is accessible from outside that function and set it if the condition is met, then return that variable at the end of the function.
const rows = {
"records": [
{
"context": {
"team": [
"MYTEAM-Consume-TEAM-SETUP-ADMIN"
]
},
"values": []
},
{
"context": {
"team": [
"TEAM1"
]
},
"values": [
{
"value": "red",
"label": "dd"
}
]
},
{
"context": {
"team": [
"Test"
]
},
"values": []
},
]
}
function hideContextTable(rows) {
let isEmpty = false;
const data = rows;
if (data.records && data.records.values) {
data.records.forEach(function (record) {
if (record.values.length === 0) {
isEmpty = true;
return; // this is a higher order function
// meaning: it won't leave the context of hideContextTable
}
});
}
return isEmpty;
}
const test = hideContextTable(rows);
console.log(test);

Converting JavaScript Array to JSON object

I am trying to write a for or JQuery. Each loop so that It will generate a new JSON Object from an array in a desired format. I want to output a JSON Object from an input JavaScript Array. I have a following input array to convert:
INPUT:
[
{
"parent": "parent_1",
"child": "abc",
"data": "data1"
},
{
"parent": "parent_1",
"child": "def",
"data": "data2"
},
{
"parent": "parent_1",
"child": "ghi",
"data": "data3"
},
{
"parent": "parent_2",
"child": "jkl",
"data": "data4"
},
{
"parent": "parent_2",
"child": "acc",
"data": "data5"
},
{
"parent": "parent_3",
"child": "mjh",
"data": "data6"
},
{
"parent": "parent_3",
"child": "fg1",
"data": "data7"
},
{
"parent": "parent_2",
"child": "dfg",
"data": "data8"
},
{
"parent": "parent_3",
"child": "jkk",
"data": "data9"
},
{
"parent": "parent_4",
"child": "3ff",
"data": "data10"
},
{
"parent": "parent_3",
"child": "mhg",
"data": "data11"
},
{
"parent": "parent_1",
"child": "gnh",
"data": "data12"
}
]
so from above array want to run a for or JQuery. Each loop so that it will generate a new JSON Object in the following format:
OUTPUT:
[
{
"parent_1": {
"child": [
{
"name": "abc",
"data": "data1"
},
{
"name": "def",
"data": "data2"
},
{
"name": "gh1",
"data": "data3"
},
{
"name": "gnh",
"data": "data12"
}
]
}
},
{
"parent_2": {
"child": [
{
"name": "jkl",
"data": "data4"
},
{
"name": "acc",
"data": "data5"
},
{
"name": "dfg",
"data": "data8"
}
]
}
},
{
"parent_3": {
"child": [
{
"name": "mjh",
"data": "data6"
},
{
"name": "fg1",
"data": "data7"
},
{
"name": "jkk",
"data": "data9"
},
{
"name": "mhg",
"data": "data11"
}
]
}
},
{
"parent_4": {
"child": [
{
"name": "3ff",
"data": "data10"
}
]
}
}
]
You could group the data by using parent as key for an object and add the rest of the object to the children array of the group.
This approach does not muate the given data.
const
data = [{ parent: "parent_1", child: "abc", data: "data1" }, { parent: "parent_1", child: "def", data: "data2" }, { parent: "parent_1", child: "ghi", data: "data3" }, { parent: "parent_2", child: "jkl", data: "data4" }, { parent: "parent_2", child: "acc", data: "data5" }, { parent: "parent_3", child: "mjh", data: "data6" }, { parent: "parent_3", child: "fg1", data: "data7" }, { parent: "parent_2", child: "dfg", data: "data8" }, { parent: "parent_3", child: "jkk", data: "data9" }, { parent: "parent_4", child: "3ff", data: "data10" }, { parent: "parent_3", child: "mhg", data: "data11" }, { parent: "parent_1", child: "gnh", data: "data12" }],
result = Object.values(data.reduce((r, { parent, ...o }) => {
r[parent] ??= { [parent]: { children: [] } };
r[parent][parent].children.push(o);
return r;
}, []));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I think you want something like this
const convertArray = (arr, field) => {
const obj = {};
arr.forEach(elem => {
const param = elem[field];
if (!Array.isArray(obj[param])) obj[param] = [];
delete elem[field];
obj[param].push(elem);
});
return Object.keys(obj).map(elem => {
return { [elem]: { child: obj[elem] } };
});
}
then you would use as
convertArray(*array*, "parent")
You can use .reduce function, for example:
var array = [ {name: 'item 1', cate: 'cate-1'}, {name: 'item 2', cate: 'cate-2'} ]
var object = array.reduce(function(obj, item) {
if (!obj[item.cate]) obj[item.cate] = {child: []};
obj[item.cate].child.push(item);
return obj;
}, {})
console.log(object);
You can use the below code for this.
var arr = [{"parent":"parent_1","child":"abc","data":"data1"},{"parent":"parent_1","child":"def","data":"data2"},{"parent":"parent_1","child":"ghi","data":"data3"},{"parent":"parent_2","child":"jkl","data":"data4"},{"parent":"parent_2","child":"acc","data":"data5"},{"parent":"parent_3","child":"mjh","data":"data6"},{"parent":"parent_3","child":"fg1","data":"data7"},{"parent":"parent_2","child":"dfg","data":"data8"},{"parent":"parent_3","child":"jkk","data":"data9"},{"parent":"parent_4","child":"3ff","data":"data10"},{"parent":"parent_3","child":"mhg","data":"data11"},{"parent":"parent_1","child":"gnh","data":"data12"}];
var result = {};
$.each(arr, function (i, item) {
if(!result[item.parent]) {
result[item.parent] = [];
}
var data = {'child': {'name': item.child, 'data': item.data}};
(result[item.parent]).push(data);
});
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

How to convert string path to JSON parent-child tree using node js?

I have been trying to convert an array of paths to the JSON parent-child tree using node js. I am following #Nenad Vracar answer for building the tree link. I am using the mentioned answer which I have slightly modified. Below is my code:
function buildTree(obj) {
let result = [];
let level = {
result
};
obj.forEach(item => {
if (typeof item.fsLocation != "undefined") {
var obj = {}
var path = ""
item.fsLocation.split('/').reduce((r, name, i, a) => {
path += "/"+name
if (!r[name]) {
r[name] = {
result:[]
};
obj = {
name,
children: r[name].result
}
if(r[name].result.length < 1){
obj["path"] = item.fsLocation
obj["fileSize"] = item.fileSize
obj["createDate"] = item.createDate
obj["editDate"] = item.editDate
obj["fileType"] = item.fileType
obj["version"] = item.version
}
r.result.push(obj)
}
return r[name];
}, level)
}
})
return result
}
obj:
[
{
"createDate":"2019-10-03T07:00:00Z",
"fileType":"pptx",
"fsLocation":"Events/Plays/Technologies/Continuity/technology.pptx",
"fileSize":46845322,
"fileName":"technology.pptx",
"editDate":"2019-10-03T07:00:00Z",
"version":"10.0"
},
{
"fileName":"operations.pptx",
"fileSize":23642178,
"fileType":"pptx",
"fsLocation":"Events/Plays/Technologies/operations.pptx",
"createDate":"2019-01-08T08:00:00Z",
"editDate":"2019-01-09T08:00:00Z",
"version":"15.0"
},
{
"fileName":"Solution.pdf",
"createDate":"2016-06-16T22:42:16Z",
"fileSize":275138,
"fsLocation":"Events/Plays/Technologies/Solution.pdf",
"fileType":"pdf",
"editDate":"2016-06-16T22:42:16Z",
"version":"1.0"
}
]
Using that above code my output is like below:
[
{
"name":"Events",
"children":[
{
"name":"Plays",
"children":[
{
"name":"Technologies",
"children":[
{
"name":"Continuity",
"children":[
{
"name":"technology.pptx",
"children":[
],
"path":"Events/Plays/Technologies/Continuity/technology.pptx",
"fileSize":46845322,
"createDate":"2019-10-03T07:00:00Z",
"editDate":"2019-10-03T07:00:00Z",
"fileType":"pptx",
"version":"10.0"
}
],
"path":"Events/Plays/Technologies/Continuity/technology.pptx",
"fileSize":46845322,
"createDate":"2019-10-03T07:00:00Z",
"editDate":"2019-10-03T07:00:00Z",
"fileType":"pptx",
"version":"10.0"
},
{
"name":"Technologies",
"children":[
{
"name":"operations.pptx",
"children":[
],
"path":"Events/Plays/Technologies/operations.pptx",
"fileSize":23642178,
"createDate":"2019-01-08T08:00:00Z",
"editDate":"2019-01-09T08:00:00Z",
"fileType":"pptx",
"version":"15.0"
},
{
"name":"Solution.pdf",
"children":[
],
"path":"Events/Plays/Technologies/Solution.pdf",
"fileSize":275138,
"createDate":"2016-06-16T22:42:16Z",
"editDate":"2016-06-16T22:42:16Z",
"fileType":"pdf",
"version":"1.0"
}
],
"path":"Events/Plays/Technologies/operations.pptx",
"fileSize":23642178,
"createDate":"2019-01-08T08:00:00",
"editDate":"2019-01-09T08:00:00Z",
"fileType":"pptx",
"version":"15.0"
}
]
}
]
}
]
}
]
I would like to get output like below
[
{
"name":"Events",
"path":"Events",
"children":[
{
"name":"Plays",
"path":"Events/Plays",
"children":[
{
"name":"Technologies",
"path":"Events/Plays/Technologies",
"children":[
{
"name":"Continuity",
"path":"Events/Plays/Technologies/Continuity",
"children":[
{
"name":"technology.pptx",
"children":[
],
"path":"Events/Plays/Technologies/Continuity/technology.pptx",
"fileSize":46845322,
"createDate":"2019-10-03T07:00:00Z",
"editDate":"2019-10-03T07:00:00Z",
"fileType":"pptx",
"version":"10.0"
}
]
},
{
"name":"Technologies",
"path":"Events/Plays/Technologies",
"children":[
{
"name":"operations.pptx",
"children":[
],
"path":"Events/Plays/Technologies/operations.pptx",
"fileSize":23642178,
"createDate":"2019-01-08T08:00:00Z",
"editDate":"2019-01-09T08:00:00Z",
"fileType":"pptx",
"version":"15.0"
},
{
"name":"Solution.pdf",
"children":[
],
"path":"Events/Plays/Technologies/Solution.pdf",
"fileSize":275138,
"createDate":"2016-06-16T22:42:16Z",
"editDate":"2016-06-16T22:42:16Z",
"fileType":"pdf",
"version":"1.0"
}
]
}
]
}
]
}
]
}
]
Any idea of how to produce the above output?
Always favor readability over fancy:
const arr = [{
"fileName": "operations.pptx",
"fileSize": 23642178,
"fileType": "pptx",
"fsLocation": "Events/Plays/Technologies/operations.pptx",
"createDate": "2019-01-08T08:00:00Z",
"editDate": "2019-01-09T08:00:00Z",
"version": "15.0"
},
{
"createDate": "2019-10-03T07:00:00Z",
"fileType": "pptx",
"fsLocation": "Events/Plays/Technologies/Continuity/technology.pptx",
"fileSize": 46845322,
"fileName": "technology.pptx",
"editDate": "2019-10-03T07:00:00Z",
"version": "10.0"
},
{
"fileName": "Solution.pdf",
"createDate": "2016-06-16T22:42:16Z",
"fileSize": 275138,
"fsLocation": "Events/Plays/Technologies/Solution.pdf",
"fileType": "pdf",
"editDate": "2016-06-16T22:42:16Z",
"version": "1.0"
}
]
const tree = {
name: 'root',
path: '',
children: []
}
for (const e of arr) {
let node = tree
const nodenames = e.fsLocation.split('/')
while (nodenames.length > 0) {
const nodename = nodenames.shift()
if (!node.children.map(e => e.name).includes(nodename)) {
node.children.push({
name: nodename,
path: [node.path, nodename].join('/'),
children: []
})
}
node = node.children.filter(e => e.name === nodename)[0]
}
}
console.log(JSON.stringify(tree, null, 2));
returns tree:
{
"name": "root",
"path": "",
"children": [
{
"name": "Events",
"path": "/Events",
"children": [
{
"name": "Plays",
"path": "/Events/Plays",
"children": [
{
"name": "Technologies",
"path": "/Events/Plays/Technologies",
"children": [
{
"name": "operations.pptx",
"path": "/Events/Plays/Technologies/operations.pptx",
"children": []
},
{
"name": "Continuity",
"path": "/Events/Plays/Technologies/Continuity",
"children": [
{
"name": "technology.pptx",
"path": "/Events/Plays/Technologies/Continuity/technology.pptx",
"children": []
}
]
},
{
"name": "Solution.pdf",
"path": "/Events/Plays/Technologies/Solution.pdf",
"children": []
}
]
}
]
}
]
}
]
}

Loop through nested Json javascript

I'm trying to loop through all the conditions for a form logic system utilizing the json-logic-js library and having issues going into the infinite nested conditions. It works when there is no additional nested operations but can't figure out away to loop through and detect if the condition contains additional conditions infinitely..
What I'm needing is this output
{
"or": [
{
"==": [
"0hxsj03jab9pjsu1",
"Rig 15"
]
},
{
"or": [
{
"==": [
"5l12cnsnxe1911bm",
"Corporate"
]
},
{
"==": [
"5l12cnsnxe1911bm",
"Pumping"
]
}
]
},
{
"and": [
{
"==": [
"69vsm5bkfb101n2n",
"Unsafe"
]
},
{
"or": [
{
"==": [
"b09ivo9r1aldu6jf",
"Yes"
]
},
{
"==": [
"0hxsj03jab9pjsu1",
"Rig 44"
]
},
{
"==": [
"0hxsj03jab9pjsu1",
"Other"
]
}
]
}
]
}
]
}
I currently have this much.
var item = {
"id":"8wj4xhwe3pd9aage",
"showif": {
"operator": "or",
"conditions": [
{
"operator": "and",
"conditions": [
{
"data": {
"fieldId": "69vsm5bkfb101n2n",
"settings": {
"values": [
"Unsafe"
]
}
}
},
{
"operator": "or",
"conditions": [
{
"data": {
"fieldId": "b09ivo9r1aldu6jf",
"settings": {
"values": [
"Yes"
]
}
}
},
{
"data": {
"fieldId": "0hxsj03jab9pjsu1",
"settings": {
"values": [
"Rig 44",
"Other"
]
}
}
}
]
}
]
},
{
"data": {
"fieldId": "0hxsj03jab9pjsu1",
"settings": {
"values": [
"Rig 15"
]
}
}
},
{
"data": {
"fieldId": "5l12cnsnxe1911bm",
"settings": {
"values": [
"Corporate",
"Pumping"
]
}
}
}
]
}
};
var condition = [];
item.showif.conditions.forEach(element => {
var orC = []
if(element.data){
element.data.settings.values.forEach(values => {
if(element.data.settings.values.length <= 1){
condition.push({"==": [element.data.fieldId,values]})
}else{
orC.push({"==": [element.data.fieldId,values]})
}
});
if(orC.length >= 1){
condition.push({"or":orC})
}
}
});
var Logic = {[item.showif.operator]: condition}
console.log(Logic)
I cant wrap my brain around this without getting lost..
I figured it out. For anyone else with this here is my code :)
var item = {
"id": "8wj4xhwe3pd9aage",
"showif": {
"operator": "or",
"conditions": [
{
"operator": "and",
"conditions": [
{
"data": {
"fieldId": "69vsm5bkfb101n2n",
"settings": {
"values": [
"Unsafe"
]
}
}
},
{
"operator": "or",
"conditions": [
{
"data": {
"fieldId": "b09ivo9r1aldu6jf",
"settings": {
"values": [
"Yes"
]
}
}
},
{
"data": {
"fieldId": "0hxsj03jab9pjsu1",
"settings": {
"values": [
"Rig 44",
"Other"
]
}
}
}
]
}
]
},
{
"data": {
"fieldId": "0hxsj03jab9pjsu1",
"settings": {
"values": [
"Rig 15"
]
}
}
},
{
"data": {
"fieldId": "5l12cnsnxe1911bm",
"settings": {
"values": [
"Corporate",
"Pumping"
]
}
}
}
]
}
};
function loopThrough(obj) {
var operator = obj.operator
var condition = [];
obj.conditions.forEach(element => {
var orC = []
if (element.data) {
element.data.settings.values.forEach(values => {
if (element.data.settings.values.length <= 1) {
condition.push({
"==": [element.data.fieldId, values]
})
} else {
orC.push({
"==": [element.data.fieldId, values]
})
}
});
if (orC.length >= 1) {
condition.push({
"or": orC
})
}
} else if (element.operator) {
condition.push(this.loopThrough(element))
}
});
return ({
[operator]: condition
})
}
console.log(loopThrough(item.showif));

merge duplicate file path in children - tree node

I am using the following json to build a tree structure.. if you notice, there are 2 children with identical file path borides and titanium, I need to merge them so that duplicate folders are not created.
my output folder structure would be
SRD 13
- borides
- titanium
- srd13_B-102.json
- srd13_B-103.json
with the following json, borides and titanium are getting repeated
Input json
parentObj =
[{
"data": {
"resTitle": "-JANAF Thermochemical Tables - SRD 13"
},
"children": [{
"data": {
"filePath": "borides"
},
"children": [{
"data": {
"filePath": "titanium"
},
"children": [{
"data": {
"filePath": "srd13_B-102.json"
},
"children": []
}]
}]
}, {
"data": {
"filePath": "borides"
},
"children": [{
"data": {
"filePath": "titanium"
},
"children": [{
"data": {
"filePath": "srd13_B-103.json"
},
"children": []
}]
}]
}]
}]
Output json would be
[{
"data": {
"resTitle": "-JANAF Thermochemical Tables - SRD 13"
},
"children": [{
"data": {
"filePath": "borides"
},
"children": [{
"data": {
"filePath": "titanium"
},
"children": [{
"data": {
"filePath": "srd13_B-102.json"
}
},
{
"data": {
"filePath": "srd13_B-103.json"
}
}
]
}]
}]
}]
I am using the following script to merge the nodes but it only looks for identical filepath in first level, but in this case there are identical file paths in second level too..
const tmp ={}
ParentObj.children.forEach((o) => {
const path = o.data.filePath;
if (tmp[path]) {
tmp[path].children = tmp[path].children || [];
tmp[path].children.push(...o.children)
} else {
tmp[path] = o;
}
});
ParentObj.children = Object.values(tmp);
I appreciate any help.
You need some recursion to achieve this. I used Array.prototype.reduce() and recursive function merge to merge duplicate children nodes:
const merge = (data) => {
return data.reduce((result, current) => {
let dup = result.find(d => d.data.filePath === current.data.filePath);
if (!dup) {
result.push(current.children && current.children.length > 0 ? {
data: current.data,
children: merge(current.children)
} : {data: current.data});
} else if (current.children && current.children.length > 0) {
dup.children = merge(dup.children.concat(current.children));
}
return result;
}, []);
};
let parentObj =
[
{
"data":{
"resTitle":"-JANAF Thermochemical Tables - SRD 13"
},
"children":[
{
"data":{
"filePath":"borides"
},
"children":[
{
"data":{
"filePath":"titanium"
},
"children":[
{
"data":{
"filePath":"srd13_B-102.json"
},
"children":[
]
}
]
}
]
},
{
"data":{
"filePath":"borides"
},
"children":[
{
"data":{
"filePath":"titanium"
},
"children":[
{
"data":{
"filePath":"srd13_B-103.json"
},
"children":[
]
}
]
}
]
}
]
}
];
console.log(JSON.stringify(merge(parentObj), null, ' '));

Categories