Loop through nested Json javascript - 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));

Related

Transform JSON array using ES 6 methods

I have the following example of an array format that needs to be transformed.
{ [
{
"condition": "$and",
"children": [
{ "column": "Title", "comparison": "$eq", "columnValue": "1" },
{ "column": "Event Status", "comparison": "$eq", "columnValue": "2" }
]
},
{
"condition": "$or",
"children": [
{
"column": "Issue Description",
"comparison": "$lt",
"columnValue": "3"
},
{ "column": "Number Label", "comparison": "$gte", "columnValue": "4" }
]
}
]}
It needs to be transformed like this...
{
[
{
"$and" : [
{
"Title" : {
"$eq" : "1"
}
},
{
"Event Status" : {
"$eq" : "2"
}
}
]
},
{
"$or" : [
{
"Issue Description" : {
"$lt" : "3"
}
},
{
"Number Label" : {
"$gte" : "4"
}
}
]
}
]
}
I've tried various iterations of map and reduce. Gotten close, but not completely there.
This is in a Vue project. Here is an example of what I tried.
const result = this.parents.map(({ condition, children }) => {
const childArray = children.reduce(
(c, v) => ({
...c,
[v.column]: { [v.comparison]: v.columnValue }
}),
{}
);
childArray.condition = condition;
return childArray;
});
This returns:
[
{
"Title": { "$eq": "1" },
"Event Status": { "$eq": "2" },
"condition": "$and"
},
{
"Issue Description": { "$lt": "3" },
"Number Label": { "$gte": "4" },
"condition": "$or"
}
]
I cannot figure out how to get the "condition" key in the right place.
ES6 computed property names will be a big help, allowing variable expression enclosed in [] square braces to compute a key value...
let inputExpressions = [
{
"condition": "$and",
"children": [
{ "column": "Title", "comparison": "$eq", "columnValue": "1" },
{ "column": "Event Status", "comparison": "$eq", "columnValue": "2" }
]
},
{
"condition": "$or",
"children": [
{
"column": "Issue Description",
"comparison": "$lt",
"columnValue": "3"
},
{ "column": "Number Label", "comparison": "$gte", "columnValue": "4" }
]
}
];
function translateExpression(expression) {
const translateClause = clause => {
return { [clause.column] : { [clause.comparison] : clause.columnValue } };
};
return { [expression.condition] : expression.children.map(translateClause) };
}
let resultExpressions = inputExpressions.map(translateExpression);
console.log(resultExpressions)

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

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": []
}
]
}
]
}
]
}
]
}

Try to query and aggregate in ElasticSearch but aggregrating not working - elasticsearch.js client

I'm trying to query my dataset for two purposes:
Match a term (resellable = true)
Order the results by their price
lowest to highest
Data set/doc is:
"data" : {
"resellable" : true,
"startingPrice" : 0,
"id" : "4emEe_r_x5DRCc5",
"buyNowPrice" : 0.006493, //Changes per object
"sub_title" : "test 1",
"title" : "test 1",
"category" : "Education",
}
//THREE OBJECTS WITH THE VALUES OF 0.006, 0.7, 1.05 FOR BUYNOWPRICE
I have three objects of these with different buyNowPrice
Query with agg is:
{
"query": {
"bool": {
"must": [
{
"term": {
"data.resellable": true
}
}
]
}
},
"from": 0,
"size": 5,
"aggs": {
"lowestPrice": {
"terms": {
"field": "data.buyNowPrice",
"order": {
"lowest_price": "desc"
}
},
"aggs": {
"lowest_price": {
"min": {
"field": "data.buyNowPrice"
}
},
"lowest_price_top_hits": {
"top_hits": {
"size": 5,
"sort": [
{
"data.buyNowPrice": {
"order": "desc"
}
}
]
}
}
}
}
}
}
The query works fine, and the results are 3 objects that have resellable = true
The issue is, the agg is not organizing the results based off the lowest buy now price.
Each result, the order of buyNowPrice is: 1.06, 0.006, 0.7 - which is not ordered properly.
Switching to desc has no affect, so I don't believe the agg is running at all?
EDIT:
Using the suggestion below my query now looks like:
{
"query": {
"bool": {
"must": [
{
"term": {
"data.resellable": true
}
}
]
}
},
"from": 0,
"size": 5,
"aggs": {
"lowestPrice": {
"terms": {
"field": "data.buyNowPrice",
"order": {
"lowest_price": "asc"
}
},
"aggs": {
"lowest_price": {
"min": {
"field": "data.buyNowPrice"
}
},
"lowest_price_top_hits": {
"top_hits": {
"size": 5
}
}
}
}
}
}
With the results of the query being:
total: { value: 3, relation: 'eq' },
max_score: 0.2876821,
hits: [
{
_index: 'education',
_type: 'listing',
_id: '4emEe_r_x5DRCc5', <--- buyNowPrice of 0.006
_score: 0.2876821,
_source: [Object]
},
{
_index: 'education',
_type: 'listing',
_id: '4ee_r_x5DRCc5', <--- buyNowPrice of 1.006
_score: 0.18232156,
_source: [Object]
},
{
_index: 'education',
_type: 'listing',
_id: '4444_r_x5DRCc5', <--- buyNowPrice of 0.7
_score: 0.18232156,
_source: [Object]
}
]
}
EDIT 2:
Removing the query for resellable = true the aggregation will sort properly and return the items in the proper order. But with the query for resellable included, it does not.
I'm assuming this has to do with the _score property overriding the sorting from agg? How would this be fixed
You can use a bucket sort aggregation that is a parent pipeline
aggregation which sorts the buckets of its parent multi-bucket
aggregation. Zero or more sort fields may be specified together with
the corresponding sort order.
Adding a working example (using the same index data as given in the question), search query, and search result
Search Query:
{
"query": {
"bool": {
"must": [
{
"term": {
"data.resellable": true
}
}
]
}
},
"from": 0,
"size": 5,
"aggs": {
"source": {
"terms": {
"field": "data.buyNowPrice"
},
"aggs": {
"latest": {
"top_hits": {
"_source": {
"includes": [
"data.buyNowPrice",
"data.id"
]
}
}
},
"highest_price": {
"max": {
"field": "data.buyNowPrice"
}
},
"bucket_sort_order": {
"bucket_sort": {
"sort": {
"highest_price": {
"order": "desc"
}
}
}
}
}
}
}
}
Search Result:
"buckets": [
{
"key": 1.0499999523162842,
"doc_count": 1,
"highest_price": {
"value": 1.0499999523162842
},
"latest": {
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.08701137,
"hits": [
{
"_index": "stof_64364468",
"_type": "_doc",
"_id": "3",
"_score": 0.08701137,
"_source": {
"data": {
"id": "4emEe_r_x5DRCc5",
"buyNowPrice": 1.05 <-- note this
}
}
}
]
}
}
},
{
"key": 0.699999988079071,
"doc_count": 1,
"highest_price": {
"value": 0.699999988079071
},
"latest": {
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.08701137,
"hits": [
{
"_index": "stof_64364468",
"_type": "_doc",
"_id": "2",
"_score": 0.08701137,
"_source": {
"data": {
"id": "4emEe_r_x5DRCc5",
"buyNowPrice": 0.7 <-- note this
}
}
}
]
}
}
},
{
"key": 0.006000000052154064,
"doc_count": 1,
"highest_price": {
"value": 0.006000000052154064
},
"latest": {
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.08701137,
"hits": [
{
"_index": "stof_64364468",
"_type": "_doc",
"_id": "1",
"_score": 0.08701137,
"_source": {
"data": {
"id": "4emEe_r_x5DRCc5",
"buyNowPrice": 0.006 <-- note this
}
}
}
]
}
}
}
]
Update 1:
If you modify your search query as :
{
"query": {
"bool": {
"must": [
{
"term": {
"data.resellable": true
}
}
]
}
},
"aggs": {
"lowestPrice": {
"terms": {
"field": "data.buyNowPrice",
"order": {
"lowest_price": "asc" <-- change the order here
}
},
"aggs": {
"lowest_price": {
"min": {
"field": "data.buyNowPrice"
}
},
"lowest_price_top_hits": {
"top_hits": {
"size": 5
}
}
}
}
}
}
Running the above search query also, you will get your required results.

Unexpected data sorting result after filtering from parent and child node

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.

Categories