Tree massiv get all the links of the elements - javascript

I have and object literal that is essentially a tree that does not have a fixed number of levels.
How can I search for a tree for a particular node, and then return this node with connection parameters when it is found in a spectacular javascript manner?
var data = [{
title: 'topNode',
id: 1,
children: [{
title: 'node1',
id: 2,
children: [{
title: 'randomNode_1',
id: 3,
},
{
title: 'node2',
id: 4,
children: [{
title: 'randomNode_2',
id: 5,
children: [{
title: 'node2',
id: 1111,
children: [{
title: 'randomNode_3',
id: 1232,
}]
}]
}]
}
]
}]
}];
tree build   what should be done
tree built from api
serializeGoals: state => type => {
const _goals = JSON.parse(JSON.stringify(state.goals))
return {
title: 'Стратегия',
expand: true,
forst: true,
children: _goals.filter((item) => {
if (item.type !== null && type.some(typeID => typeID === item.type.id)) {
item.shadow = true
} else if (item.type !== null && type.length > 0) {
item.shadow = false
item.type.color = '#ECECEC'
}
item.children = _goals.filter((children) => {
if (children.parent_id === item.id) {
if (children.type !== null && type.some(typeID => typeID === children.type.id)) {
children.shadow = true
} else if (children.type !== null && type.length > 0) {
children.type.color = '#ECECEC'
children.shadow = false
}
return true
}
return false
})
return item.parent_id === null
})
}
}
Get api server JSON array
parent_id - element parent
[{
"id": 5,
"parent_id": null,
"responsible_id": null,
"type_id": 4,
"title": "Тестовая цель - 5",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 4, "title": "Персонал", "color": "#6190e8"}
}, {
"id": 7,
"parent_id": null,
"responsible_id": null,
"type_id": 4,
"title": "Тестовая цель - 7",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 4, "title": "Персонал", "color": "#6190e8"}
}, {
"id": 9,
"parent_id": null,
"responsible_id": null,
"type_id": 4,
"title": "Тестовая цель - 9",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 4, "title": "Персонал", "color": "#6190e8"}
}, {
"id": 11,
"parent_id": null,
"responsible_id": null,
"type_id": 3,
"title": "Тестовая цель - 11",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 3, "title": "Процессы", "color": "#13ce66"}
}, {
"id": 13,
"parent_id": null,
"responsible_id": null,
"type_id": 4,
"title": "Тестовая цель - 13",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 4, "title": "Персонал", "color": "#6190e8"}
}, {
"id": 15,
"parent_id": null,
"responsible_id": null,
"type_id": 2,
"title": "Тестовая цель - 15",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 2, "title": "Клиенты", "color": "#ff4949"}
}, {
"id": 17,
"parent_id": null,
"responsible_id": null,
"type_id": 4,
"title": "Тестовая цель - 17",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 4, "title": "Персонал", "color": "#6190e8"}
}, {
"id": 19,
"parent_id": null,
"responsible_id": null,
"type_id": 4,
"title": "Тестовая цель - 19",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 4, "title": "Персонал", "color": "#6190e8"}
}, {
"id": 20,
"parent_id": 11,
"responsible_id": null,
"type_id": 2,
"title": "Тестовая цель - 20",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 2, "title": "Клиенты", "color": "#ff4949"}
}, {
"id": 21,
"parent_id": null,
"responsible_id": null,
"type_id": 3,
"title": "Тестовая цель - 21",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 3, "title": "Процессы", "color": "#13ce66"}
}, {
"id": 23,
"parent_id": null,
"responsible_id": null,
"type_id": 2,
"title": "Тестовая цель - 23",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 2, "title": "Клиенты", "color": "#ff4949"}
}, {
"id": 25,
"parent_id": null,
"responsible_id": null,
"type_id": 1,
"title": "Тестовая цель - 25",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 1, "title": "Финансы", "color": "#ffc82c"}
}, {
"id": 26,
"parent_id": 15,
"responsible_id": null,
"type_id": 2,
"title": "Тестовая цель - 26",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 2, "title": "Клиенты", "color": "#ff4949"}
}, {
"id": 27,
"parent_id": null,
"responsible_id": null,
"type_id": 1,
"title": "Тестовая цель - 27",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 1, "title": "Финансы", "color": "#ffc82c"}
}, {
"id": 28,
"parent_id": 7,
"responsible_id": null,
"type_id": 2,
"title": "Тестовая цель - 28",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 2, "title": "Клиенты", "color": "#ff4949"}
}, {
"id": 29,
"parent_id": null,
"responsible_id": null,
"type_id": 4,
"title": "Тестовая цель - 29",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 4, "title": "Персонал", "color": "#6190e8"}
}, {
"id": 31,
"parent_id": null,
"responsible_id": null,
"type_id": 2,
"title": "Тестовая цель - 31",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 2, "title": "Клиенты", "color": "#ff4949"}
}, {
"id": 33,
"parent_id": null,
"responsible_id": null,
"type_id": 3,
"title": "Тестовая цель - 33",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 3, "title": "Процессы", "color": "#13ce66"}
}, {
"id": 34,
"parent_id": 31,
"responsible_id": null,
"type_id": 4,
"title": "Тестовая цель - 34",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 4, "title": "Персонал", "color": "#6190e8"}
}, {
"id": 35,
"parent_id": null,
"responsible_id": null,
"type_id": 1,
"title": "Тестовая цель - 35",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 1, "title": "Финансы", "color": "#ffc82c"}
}, {
"id": 36,
"parent_id": 34,
"responsible_id": null,
"type_id": 1,
"title": "Тестовая цель - 36",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 1, "title": "Финансы", "color": "#ffc82c"}
}, {
"id": 37,
"parent_id": null,
"responsible_id": null,
"type_id": 4,
"title": "Тестовая цель - 37",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 4, "title": "Персонал", "color": "#6190e8"}
}, {
"id": 39,
"parent_id": null,
"responsible_id": null,
"type_id": 3,
"title": "Тестовая цель - 39",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 3, "title": "Процессы", "color": "#13ce66"}
}, {
"id": 40,
"parent_id": 34,
"responsible_id": null,
"type_id": 2,
"title": "Тестовая цель - 40",
"description": null,
"period": 2018,
"weight": null,
"responsible": null,
"type": {"id": 2, "title": "Клиенты", "color": "#ff4949"}
}]

I would use a recursive function to iterate through the tree and return the node when the expected one is found (I assumed the title is the search criteria) or return null if none was found.
In example :
var data = [
{
title: 'topNode',
id: 1,
children: [
{
title: 'node1',
id: 2,
children: [
{
title: 'randomNode_1',
id: 3,
},
{
title: 'node2',
id: 4,
children: [
{
title: 'randomNode_2',
id: 5,
children: [
{
title: 'node2',
id: 1111,
children: [
{
title: 'randomNode_3',
id: 1232,
}]
}]
}]
}]
}]
}];
function FindSpecificData(node, titleToFind)
{
let newNode = null;
for (let i = 0; i < node.length; ++i)
{
if (node[i].title == titleToFind)
newNode = node[i];
else if ('children' in node[i])
newNode = FindSpecificData(node[i].children, titleToFind);
if (newNode != null)
return (newNode);
}
return (null);
}
console.log(FindSpecificData(data, 'randomNode_2'));
console.log(FindSpecificData(data, 'randomNode_1'));
console.log(FindSpecificData(data, 'missing node'));

Try this simple method to find out your node
function getNode(node) {
if (node.title === 'randomNode_3') {
return true;
} else if (!node.children && !node.id) {
return false;
} else {
if (node.children) {
for (var i = 0; i < node.children.length; i++) {
getNode(node.children[i])
}
}
}
}
getNode(data[0])

Related

How to sum two values in array together in angular

I have a list of available stock that I get Via Api
the list looks like this:
{
"Total": 4,
"Page": 1,
"ProductAvailabilityList": [
{
"ID": "53350e22-0a89-4bdd-b11c-90bb3315dbe1",
"SKU": "test product 1",
"Name": "Test product 1",
"Barcode": null,
"Location": "Main Warehouse",
"Bin": null,
"Batch": null,
"ExpiryDate": null,
"OnHand": 0,
"Allocated": 1,
"Available": 1,
"OnOrder": 0,
"StockOnHand": 0
},
{
"ID": "92a8c8fd-318e-455a-945c-8c5f588c055e",
"SKU": "test product 2",
"Name": "Test product 2",
"Barcode": null,
"Location": "Main Warehouse",
"Bin": null,
"Batch": null,
"ExpiryDate": null,
"OnHand": 0,
"Allocated": 1,
"Available": 1,
"OnOrder": 0,
"StockOnHand": 0
},
{
"ID": "a2bd1fc5-f52c-4005-89a7-b9fdb4f180e1",
"SKU": "test product 3",
"Name": "Test product 3",
"Barcode": null,
"Location": "Main Warehouse",
"Bin": null,
"Batch": null,
"ExpiryDate": null,
"OnHand": 0,
"Allocated": 1,
"Available": 1,
"OnOrder": 0,
"StockOnHand": 0
},
{
"ID": "3e14fcbc-6e80-4c36-8c2c-36e29f79e192",
"SKU": "test product 4",
"Name": "Test product 4",
"Barcode": null,
"Location": "Main Warehouse",
"Bin": null,
"Batch": null,
"ExpiryDate": null,
"OnHand": 0,
"Allocated": 5,
"Available": 2,
"OnOrder": 0,
"StockOnHand": 0
}
]
}
I would like to sum together the total of stock on hand for a specific item the problem that I am having is that if there is an item with 2 different batch nr it creates two different array groups
I am pretty sure that your question is missing some information (like expected result), but nevertheless you can use the following code to get the total "stock on hand" for a specific item:
let items= {
"Total": 4,
"Page": 1,
"ProductAvailabilityList": [
{
"ID": "a2bd1fc5-f52c-4005-89a7-b9fdb4f180e1",
"SKU": "test product 1",
"Name": "Test product 1",
"Barcode": null,
"Location": "Main Warehouse",
"Bin": null,
"Batch": null,
"ExpiryDate": null,
"OnHand": 0,
"Allocated": 1,
"Available": 1,
"OnOrder": 0,
"StockOnHand": 2
},
{
"ID": "92a8c8fd-318e-455a-945c-8c5f588c055e",
"SKU": "test product 2",
"Name": "Test product 2",
"Barcode": null,
"Location": "Main Warehouse",
"Bin": null,
"Batch": null,
"ExpiryDate": null,
"OnHand": 0,
"Allocated": 1,
"Available": 1,
"OnOrder": 0,
"StockOnHand": 0
},
{
"ID": "a2bd1fc5-f52c-4005-89a7-b9fdb4f180e1",
"SKU": "test product 3",
"Name": "Test product 3",
"Barcode": null,
"Location": "Main Warehouse",
"Bin": null,
"Batch": null,
"ExpiryDate": null,
"OnHand": 0,
"Allocated": 1,
"Available": 1,
"OnOrder": 0,
"StockOnHand": 5
},
{
"ID": "3e14fcbc-6e80-4c36-8c2c-36e29f79e192",
"SKU": "test product 4",
"Name": "Test product 4",
"Barcode": null,
"Location": "Main Warehouse",
"Bin": null,
"Batch": null,
"ExpiryDate": null,
"OnHand": 0,
"Allocated": 5,
"Available": 2,
"OnOrder": 0,
"StockOnHand": 0
}
]
};
function stockSum(list: typeof items.ProductAvailabilityList, productId: string): number {
return list.filter(item => item.ID === productId).reduce((sum, item) => sum + item.StockOnHand, 0);
}
console.log(stockSum(items.ProductAvailabilityList, "a2bd1fc5-f52c-4005-89a7-b9fdb4f180e1"))
// this logs the number 7

Array object grouping in JavaScript

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

Unable to push children into parent based on parentId using JS

I am unable to push childEntries into parent based on parentId using JS. Actually I need to populate the data into a tree view table.
Here is the JSON I got from API
[{
"displayName": "",
"order": 1,
"status": "Active",
"description": "Application Top Section",
"createDate": "2020-01-01 12:00:00",
"parentId": 0,
"modifiedDate": "2020-01-01 12:00:00",
"id": 0,
"type": "section"
}, {
"displayName": "",
"order": 1,
"status": "Active",
"description": "Application Side Navigation Section",
"createDate": "2020-01-01 12:00:00",
"parentId": 1,
"modifiedDate": "2020-01-01 12:00:00",
"id": 1,
"type": "section"
}, {
"displayName": "Puente Dashboard",
"order": 1,
"status": "Active",
"description": "Application Dashboard",
"createDate": "2020-01-01 12:00:00",
"parentId": 1,
"modifiedDate": "2020-01-01 12:00:00",
"id": 2,
"type": "link"
}, {
"displayName": "Security",
"order": 2,
"status": "Active",
"description": "Security Management",
"createDate": "2020-01-01 12:00:00",
"parentId": 1,
"modifiedDate": "2020-01-01 12:00:00",
"id": 3,
"type": "link"
}, {
"displayName": "User",
"order": 1,
"status": "Active",
"description": "User Management",
"createDate": "2020-01-01 12:00:00",
"parentId": 3,
"modifiedDate": "2020-01-01 12:00:00",
"id": 4,
"type": "link"
}, {
"displayName": "Role",
"order": 2,
"status": "Active",
"description": "Role Management",
"createDate": "2020-01-01 12:00:00",
"parentId": 3,
"modifiedDate": "2020-01-01 12:00:00",
"id": 5,
"type": "link"
}, {
"displayName": "Widget",
"order": 3,
"status": "Active",
"description": "Widget Management",
"createDate": "2020-01-01 12:00:00",
"parentId": 3,
"modifiedDate": "2020-01-01 12:00:00",
"id": 6,
"type": "link"
}]
And expected JSON is
[{
"displayName": "",
"order": 1,
"status": "Active",
"description": "Application Top Section",
"createDate": "2020-01-01 12:00:00",
"parentId": 0,
"modifiedDate": "2020-01-01 12:00:00",
"id": 0,
"type": "section"
},
{
"displayName": "",
"order": 1,
"status": "Active",
"description": "Application Side Navigation Section",
"createDate": "2020-01-01 12:00:00",
"parentId": 1,
"modifiedDate": "2020-01-01 12:00:00",
"id": 1,
"type": "section",
"childEntries": [{
"displayName": "Puente Dashboard",
"order": 1,
"status": "Active",
"description": "Application Dashboard",
"createDate": "2020-01-01 12:00:00",
"parentId": 1,
"modifiedDate": "2020-01-01 12:00:00",
"id": 2,
"type": "link"
},
{
"displayName": "Security",
"order": 2,
"status": "Active",
"description": "Security Management",
"createDate": "2020-01-01 12:00:00",
"parentId": 1,
"modifiedDate": "2020-01-01 12:00:00",
"id": 3,
"type": "link",
"childEntries": [{
"displayName": "User",
"order": 1,
"status": "Active",
"description": "User Management",
"createDate": "2020-01-01 12:00:00",
"parentId": 3,
"modifiedDate": "2020-01-01 12:00:00",
"id": 4,
"type": "link"
},
{
"displayName": "Role",
"order": 2,
"status": "Active",
"description": "Role Management",
"createDate": "2020-01-01 12:00:00",
"parentId": 3,
"modifiedDate": "2020-01-01 12:00:00",
"id": 5,
"type": "link"
},
{
"displayName": "Widget",
"order": 3,
"status": "Active",
"description": "Widget Management",
"createDate": "2020-01-01 12:00:00",
"parentId": 3,
"modifiedDate": "2020-01-01 12:00:00",
"id": 6,
"type": "link"
}
]
}
]
}
]
Using below code only I am able to add "kind","childEntries" and "expanded". But ultimately I am not getting my expected JSON.
this.widgetsource.forEach(function (element) { if(element.parentId == 1 || element.parentId == 0 ){ element.kind = "dir"; element.expanded = false; element.childEntries = []; }
Here in this.widgetsource I have stored the raw JSON.
Could you please help me here.
Thanks in advance.
You can check if its a child when parent is not equal to itself, then find the parent and add in child list.
const parsedObject = JSON.parse(`[{ "displayName": "", "order": 1, "status": "Active", "description": "Application Top Section", "createDate": "2020-01-01 12:00:00", "parentId": 0, "modifiedDate": "2020-01-01 12:00:00", "id": 0, "type": "section" }, { "displayName": "", "order": 1, "status": "Active", "description": "Application Side Navigation Section", "createDate": "2020-01-01 12:00:00", "parentId": 1, "modifiedDate": "2020-01-01 12:00:00", "id": 1, "type": "section" }, { "displayName": "Puente Dashboard", "order": 1, "status": "Active", "description": "Application Dashboard", "createDate": "2020-01-01 12:00:00", "parentId": 1, "modifiedDate": "2020-01-01 12:00:00", "id": 2, "type": "link" }, { "displayName": "Security", "order": 2, "status": "Active", "description": "Security Management", "createDate": "2020-01-01 12:00:00", "parentId": 1, "modifiedDate": "2020-01-01 12:00:00", "id": 3, "type": "link" }, { "displayName": "User", "order": 1, "status": "Active", "description": "User Management", "createDate": "2020-01-01 12:00:00", "parentId": 3, "modifiedDate": "2020-01-01 12:00:00", "id": 4, "type": "link" }, { "displayName": "Role", "order": 2, "status": "Active", "description": "Role Management", "createDate": "2020-01-01 12:00:00", "parentId": 3, "modifiedDate": "2020-01-01 12:00:00", "id": 5, "type": "link" }, { "displayName": "Widget", "order": 3, "status": "Active", "description": "Widget Management", "createDate": "2020-01-01 12:00:00", "parentId": 3, "modifiedDate": "2020-01-01 12:00:00", "id": 6, "type": "link" }]`);
/**
* converting into a map for efficient access by ID id:Object.
*/
const idMap = parsedObject.reduce((accum,obj)=>{
accum[obj.id] = obj;
return accum;
},{});
const categorisedList = [];
parsedObject.forEach(obj=>{
if(obj.parentId === obj.id){
categorisedList.push(obj);
}else{
const parent = idMap[obj.parentId];
if(!parent.childEntries){
parent.childEntries=[];
}
parent.childEntries.push(obj);
}
});
console.log(categorisedList);
//If you need as JSON String.
const json = JSON.stringify(categorisedList);

For to mount json

I have in variable bookUnitIdInformacoes this array of objects:
[
{
"id": 5,
"book_id": 33,
"unit": 1,
"sequence": 1,
"description": "UNIT_01_GRAMMAR",
"qt_question": 5,
"status": false,
"user_id": 1,
"created_at": "2019-12-27 08:11:21",
"updated_at": "2019-12-30 14:54:12",
"miniature": null
},
{
"id": 6,
"book_id": 33,
"unit": 1,
"sequence": 2,
"description": "UNIT_01_VOCABULARY",
"qt_question": 5,
"status": false,
"user_id": 1,
"created_at": "2019-12-27 08:11:39",
"updated_at": "2019-12-27 08:11:39",
"miniature": null
},
{
"id": 7,
"book_id": 33,
"unit": 2,
"sequence": 1,
"description": "UNIT_02_GRAMMAR",
"qt_question": 5,
"status": false,
"user_id": 1,
"created_at": "2019-12-27 08:11:46",
"updated_at": "2019-12-27 08:11:46",
"miniature": null
},
{
"id": 8,
"book_id": 39,
"unit": 1,
"sequence": 1,
"description": "UNIT_01_GRAMMAR",
"qt_question": 5,
"status": false,
"user_id": 1,
"created_at": "2019-12-30 11:07:09",
"updated_at": "2019-12-30 15:03:50",
"miniature": null
}
]
I have in the variable idioma this array of objects:
[
{
"id": 13,
"code": "ING-NOT-2019",
"description": "Inglês Noturno 2019",
"start_date": "2019-12-30T03:00:00.000Z",
"end_date": "2019-12-31T03:00:00.000Z",
"period": "Noturno",
"language": "Inglês",
"status": false,
"user_id": 1,
"created_at": "2019-12-30 10:04:47",
"updated_at": "2020-01-05 16:08:00",
"language_substring": "US"
},
{
"id": 14,
"code": "ESP-MAN-2019",
"description": "Espanhol manhã 2019",
"start_date": "2019-12-30T03:00:00.000Z",
"end_date": "2019-12-31T03:00:00.000Z",
"period": "Manhã",
"language": "Espanhol",
"status": false,
"user_id": 1,
"created_at": "2019-12-30 11:06:44",
"updated_at": "2019-12-30 11:06:44",
"language_substring": null
}
]
I need to create a for() that while the column book_id is equal the index+1, insert in idioma[i].quiz the value of the bookUnitIdInformacoes[i] and when the book_id of the bookUnitIdInformacoes array is different, put in the next position of idioma[i]quiz, so i need this json:
[
{
"id": 13,
"code": "ING-NOT-2019",
"description": "Inglês Noturno 2019",
"start_date": "2019-12-30T03:00:00.000Z",
"end_date": "2019-12-31T03:00:00.000Z",
"period": "Noturno",
"language": "Inglês",
"status": false,
"user_id": 1,
"created_at": "2019-12-30 10:04:47",
"updated_at": "2020-01-05 16:08:00",
"language_substring": "US",
"quiz": [
{
"id": 5,
"book_id": 33,
"unit": 1,
"sequence": 1,
"description": "UNIT_01_GRAMMAR",
"qt_question": 5,
"status": false,
"user_id": 1,
"created_at": "2019-12-27 08:11:21",
"updated_at": "2019-12-30 14:54:12",
"miniature": null
},
{
"id": 6,
"book_id": 33,
"unit": 1,
"sequence": 2,
"description": "UNIT_01_VOCABULARY",
"qt_question": 5,
"status": false,
"user_id": 1,
"created_at": "2019-12-27 08:11:39",
"updated_at": "2019-12-27 08:11:39",
"miniature": null
},
{
"id": 7,
"book_id": 33,
"unit": 2,
"sequence": 1,
"description": "UNIT_02_GRAMMAR",
"qt_question": 5,
"status": false,
"user_id": 1,
"created_at": "2019-12-27 08:11:46",
"updated_at": "2019-12-27 08:11:46",
"miniature": null
}
]
},
{
"id": 14,
"code": "ESP-MAN-2019",
"description": "Espanhol manhã 2019",
"start_date": "2019-12-30T03:00:00.000Z",
"end_date": "2019-12-31T03:00:00.000Z",
"period": "Manhã",
"language": "Espanhol",
"status": false,
"user_id": 1,
"created_at": "2019-12-30 11:06:44",
"updated_at": "2019-12-30 11:06:44",
"language_substring": null,
"quiz": [
{
"id": 8,
"book_id": 39,
"unit": 1,
"sequence": 1,
"description": "UNIT_01_GRAMMAR",
"qt_question": 5,
"status": false,
"user_id": 1,
"created_at": "2019-12-30 11:07:09",
"updated_at": "2019-12-30 15:03:50",
"miniature": null
}
]
}
]
I try something like:
for(let i=0;i<quizAbertos.length;i++){
if(i+1 === quizAbertos.length){
break;
}else{
if(bookUnitIdInformacoes[i].book_id === bookUnitIdInformacoes[i+1].book_id){
idioma[i].quiz = bookUnitIdInformacoes[i]
}
}
But i'm getting wrong json..
#Edit:
Actually i'm trying something like:
let book_id
let i_book_id = 0
let i_mudou_book_id = 0;
for(let i=0;i<bookUnitIdInformacoes.length;i++){
if(bookUnitIdInformacoes[i+1] === undefined){
book_id = bookUnitIdInformacoes[bookUnitIdInformacoes.length-1].book_id
}else{
if(bookUnitIdInformacoes[i].book_id === bookUnitIdInformacoes[i+1].book_id){
i_mudou_book_id++
}
}
}
idioma[0].quiz = bookUnitIdInformacoes.splice(0,i_mudou_book_id+1)
idioma[1].quiz = bookUnitIdInformacoes
but this way if i have more than 2 length i will be have problems and if i have only one length i will be too have problems.
First, you can group the bookUnitIdInfomacoes by book_id. This can be done by reducing the array into an object of key => value pairs as book_id => array of books:
{
"33": [
{
"id": 5,
"book_id": 33,
...
},
{
"id": 6,
"book_id": 33,
...
},
{
"id": 7,
"book_id": 33,
...
}
],
"39": [
{
"id": 8,
"book_id": 39,
...
}
]
}
Then, using Object.values will allow us to retrieve only the values of this groupedObj object. This will give us:
[
[
{
"id": 5,
"book_id": 33,
...
},
{
"id": 6,
"book_id": 33,
...
},
{
"id": 7,
"book_id": 33,
...
}
],
[
{
"id": 8,
"book_id": 39,
...
}
]
]
Lastly, we will have to map idiomas and add the corresponding book group into a new property called quizz. For a given idioma, we know its position in idiomas thanks to the second argument of map: i. We can simply do grouped[i] to get the corresponding group of books.
const groupedObj = bookUnitIdInformacoes.reduce((grouped, info) => {
grouped[info.book_id] = grouped[info.book_id] || [];
grouped[info.book_id].push(info);
return grouped;
}, {});
const grouped = Object.values(groupedObj);
const result = idiomas.map((idioma, i) => ({
...idioma,
quizz: grouped[i]
}));
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script>const bookUnitIdInformacoes=[{id:5,book_id:33,unit:1,sequence:1,description:"UNIT_01_GRAMMAR",qt_question:5,status:!1,user_id:1,created_at:"2019-12-27 08:11:21",updated_at:"2019-12-30 14:54:12",miniature:null},{id:6,book_id:33,unit:1,sequence:2,description:"UNIT_01_VOCABULARY",qt_question:5,status:!1,user_id:1,created_at:"2019-12-27 08:11:39",updated_at:"2019-12-27 08:11:39",miniature:null},{id:7,book_id:33,unit:2,sequence:1,description:"UNIT_02_GRAMMAR",qt_question:5,status:!1,user_id:1,created_at:"2019-12-27 08:11:46",updated_at:"2019-12-27 08:11:46",miniature:null},{id:8,book_id:39,unit:1,sequence:1,description:"UNIT_01_GRAMMAR",qt_question:5,status:!1,user_id:1,created_at:"2019-12-30 11:07:09",updated_at:"2019-12-30 15:03:50",miniature:null}],idiomas=[{id:13,code:"ING-NOT-2019",description:"Inglês Noturno 2019",start_date:"2019-12-30T03:00:00.000Z",end_date:"2019-12-31T03:00:00.000Z",period:"Noturno",language:"Inglês",status:!1,user_id:1,created_at:"2019-12-30 10:04:47",updated_at:"2020-01-05 16:08:00",language_substring:"US"},{id:14,code:"ESP-MAN-2019",description:"Espanhol manhã 2019",start_date:"2019-12-30T03:00:00.000Z",end_date:"2019-12-31T03:00:00.000Z",period:"Manhã",language:"Espanhol",status:!1,user_id:1,created_at:"2019-12-30 11:06:44",updated_at:"2019-12-30 11:06:44",language_substring:null}];</script>

How to remove all empty array childrens [] from a nested JSON recursively [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I've a JSON response as below.I'm using nested JSON data from my GeoRegionCountries APIController & custom class TreeView is used to format the data as per the required nested structure of plugin I'm using. I am using a combo multi select Treeview using this jquery plugin Multi-Select Drop Down Tree Plugin you can see it by this link jquery plugin Multi-Select Drop Down Tree Plugin
[
{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [
{
"Id": 7,
"Title": "Northwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1,
"Subs": []
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1,
"Subs": []
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1,
"Subs": []
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null,
"Subs": []
},
{
"Id": 3,
"Title": "France",
"ParentId": null,
"Subs": []
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null,
"Subs": []
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null,
"Subs": []
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null,
"Subs": []
}
]
I want to remove all "Subs" with empty array.
[
{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [
{
"Id": 7,
"Title": "Northwest",
"ParentId": 1
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null
},
{
"Id": 3,
"Title": "France",
"ParentId": null
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null
}
]
What is the best way to deep clean this? I tried different solutions in Stackopverflow but all i got is Object object in place of empty Subs - which i don't want.
[
{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [
{
"Id": 7,
"Title": "Northwest",
"ParentId": 1,
Object object
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1,
Object object
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1,
Object object
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1,
Object object
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1,
Object object
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null,
Object object
},
{
"Id": 3,
"Title": "France",
"ParentId": null,
Object object
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null,
Object object
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null,
Object object
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null,
Object object
}
]
which is not i want
You can use _.transform() to recursively check for a specific key (Subs), and remove it if it's value is empty:
const { transform, isObject, isEmpty } = _;
const removeEmpty = (obj, key) =>
transform(obj, (r, v, k) => {
if(k === key && isEmpty(v)) return;
r[k] = isObject(v) ? removeEmpty(v, key) : v;
});
const tree = [{"Id":1,"Title":"United States","ParentId":null,"Subs":[{"Id":7,"Title":"Northwest","ParentId":1,"Subs":[]},{"Id":8,"Title":"Northeast","ParentId":1,"Subs":[]},{"Id":9,"Title":"Central","ParentId":1,"Subs":[]},{"Id":10,"Title":"Southwest","ParentId":1,"Subs":[]},{"Id":18,"Title":"Southeast","ParentId":1,"Subs":[]}]},{"Id":2,"Title":"Canada","ParentId":null,"Subs":[]},{"Id":3,"Title":"France","ParentId":null,"Subs":[]},{"Id":4,"Title":"Germany","ParentId":null,"Subs":[]},{"Id":5,"Title":"Australia","ParentId":null,"Subs":[]},{"Id":6,"Title":"United Kingdom","ParentId":null,"Subs":[]}]
const result = removeEmpty(tree, 'Subs');
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
The correct answer would be this:
let array = [
{
'Id': 1,
'Title': 'United States',
'ParentId': null,
'Subs': [
{
'Id': 7,
'Title': 'Northwest',
'ParentId': 1,
'Subs': []
},
{
'Id': 8,
'Title': 'Northeast',
'ParentId': 1,
'Subs': []
},
{
'Id': 9,
'Title': 'Central',
'ParentId': 1,
'Subs': []
},
{
'Id': 10,
'Title': 'Southwest',
'ParentId': 1,
'Subs': []
},
{
'Id': 18,
'Title': 'Southeast',
'ParentId': 1,
'Subs': []
}
]
},
{
'Id': 2,
'Title': 'Canada',
'ParentId': null,
'Subs': []
},
{
'Id': 3,
'Title': 'France',
'ParentId': null,
'Subs': []
},
{
'Id': 4,
'Title': 'Germany',
'ParentId': null,
'Subs': []
},
{
'Id': 5,
'Title': 'Australia',
'ParentId': null,
'Subs': []
},
{
'Id': 6,
'Title': 'United Kingdom',
'ParentId': null,
'Subs': []
}
]
let newArray = array.map(item=> {
if (item.Subs.length===0){
delete item.Subs
return item
}
item.Subs = item.Subs.map(item=>{
if (item.Subs.length===0){
delete item.Subs
return item
}
})
return item
}
)
console.log(newArray)
let data = [
{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [
{
"Id": 7,
"Title": "Northwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1,
"Subs": []
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1,
"Subs": []
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1,
"Subs": []
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null,
"Subs": []
},
{
"Id": 3,
"Title": "France",
"ParentId": null,
"Subs": []
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null,
"Subs": []
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null,
"Subs": []
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null,
"Subs": []
}
];
data = data.map(row=>{
if (!row.Subs.length) {
let {Subs,...r} = row;
return r;
} return row
})
console.log(data);
write two functions and pass the function that iterates through your array to a map function on data as shown below
function formatData(val) {
if (val.Subs.length > 0) val.Subs.map(a => a.Subs.length > 0 ? formatData(a.Subs) : deleteSubs(a));
else deleteSubs(val);
return val;
}
function deleteSubs(val) {
delete val.Subs;
}
var data = [{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [{
"Id": 7,
"Title": "Northwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1,
"Subs": []
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1,
"Subs": []
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1,
"Subs": []
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null,
"Subs": []
},
{
"Id": 3,
"Title": "France",
"ParentId": null,
"Subs": []
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null,
"Subs": []
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null,
"Subs": []
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null,
"Subs": []
}
]
console.log(data.map(formatData))

Categories