Hi have this array:
[ {
"Navn": "Long Island Iced Tea",
"Nummer": "2",
"Glas i ml": "250",
"Instruktioner": "",
"a": "Hæld is i glasset",
"b": "pynt med en skive lime",
"Ingredienser": [
{
"Type": "Spiritus",
"Del1": [
{
"Cointreau": 20
}
],
"Del2": [
{
"Gin": 20
}
],
"Del3": [
{
"Rom_Lys": 20
}
],
"Del4": [
{
"Tequila": 20
}
],
"Del5": [
{
"Vodka": 20
}
]
},
{
"Type": "Vand/Juice",
"Del1": [
{
"Cola": 40
}
],
"Del2": [
{
"Sprite": 20
}
]
},
{
"Type": "Mixer",
"Del1": [
{
"Lime_Sirup": 20
}
]
}
]
}]
Its for a Cocktailmachine.
And i want to filter it by "Del1" searching for (example) "Rom_Lys" & "Cola" & "Vodka", and then output a new array with these specifications.
I tried searching the forums, but can't seem to find something useful. Played around with filter and includes, but cant come up with anything useful.
Thx!
If you want to get items which are contains Cola, then you can use filter and some methods:
const filterWord = 'Cola';
const result = sampleData.filter(s =>
s.Ingredienser.some(s =>
s.Del1.some( e=> e[filterWord])));
console.log(result);
An example:
let sampleData = [
{
"Navn": "Rom & Cola/ Cuba Libre",
"Nummer": "0",
"Glas i ml": "200",
"Instruktioner": "",
"a": "Hæld is i glasset",
"b": "pynt med en skive citron",
"Ingredienser": [
{
"Type": "Spiritus",
"Del1": [
{
"Rom_Lys": 40
}
]
},
{
"Type": "Vand/Juice",
"Del1": [
{
"Cola": 100
}
]
},
{
"Type": "Mixer",
"Del1": [
{}
]
}
]
},
{
"Navn": "Isbjørn",
"Nummer": "1",
"Glas i ml": "200",
"Instruktioner": "",
"a": "Hæld is i glasset",
"b": "pynt med en skive citron",
"Ingredienser": [
{
"Type": "Spiritus",
"Del1": [
{
"Vodka": 30
}
]
},
{
"Type": "Vand/Juice",
"Del1": [
{
"Sprite": 60
}
]
},
{
"Type": "Mixer",
"Del1": [
{
"Blå_Sirup": 30
}
]
}
]
}];
const filterWord = 'Cola';
const result = sampleData.filter(s => s.Ingredienser.some(s => s.Del1.some( e=> e[filterWord])));
console.log(result);
UPDATE:
If you want to check multiple key, then you can use hasOwnProperty method which checks whether the object contains desired key:
const filters = ['Cointreau', 'Gin', 'Rom_Lys'];
const result = sampleData.filter(s =>
s.Ingredienser.some(ingred => {
return Object.keys(ingred).some(k=> {
if (Array.isArray(ingred[k])) {
return ingred[k].some(s=> filters.some(f=> {
return s.hasOwnProperty(f);
}))
}
});
}
));
And the example:
let sampleData = [ {
"Navn": "Long Island Iced Tea",
"Nummer": "2",
"Glas i ml": "250",
"Instruktioner": "",
"a": "Hæld is i glasset",
"b": "pynt med en skive lime",
"Ingredienser": [
{
"Type": "Spiritus",
"Del1": [
{
"Cointreau": 20
}
],
"Del2": [
{
"Gin": 20
}
],
"Del3": [
{
"Rom_Lys": 20
}
],
"Del4": [
{
"Tequila": 20
}
],
"Del5": [
{
"Vodka": 20
}
]
},
{
"Type": "Vand/Juice",
"Del1": [
{
"Cola": 40
}
],
"Del2": [
{
"Sprite": 20
}
]
},
{
"Type": "Mixer",
"Del1": [
{
"Lime_Sirup": 20
}
]
}
]
}];
const filters = ['Cointreau', 'Gin', 'Rom_Lys'];
const result = sampleData.filter(s =>
s.Ingredienser.some(ingred => {
return Object.keys(ingred).some(k=> {
if (Array.isArray(ingred[k])) {
return ingred[k].some(s=> filters.some(f=> {
return s.hasOwnProperty(f);
}))
}
});
}
));
console.log(result);
Try using following code to filter the array.
var filtered = arr.filter(function(unique) {
for (var index = 0; index < unique.Ingredienser.length; index++) {
if (unique.Ingredienser[index].Del1[0].hasOwnProperty(selectedchoice)) {
return true;
}
}
return false;
});
Related
I'm trying to implement Role Based Access control in my nestjs project and I have a permission array as follows
let permissions = [
"newsfeeds-alerts-view",
"settings-group_details-view",
"settings-group_details-edit",
"settings-privileges-view",
"settings-privileges-edit",
"settings-my_groups-create",
"settings-my_groups-view",
"settings-my_groups-edit",
"settings-my_groups-delete",
"settings-users-view",
"settings-users-edit",
"settings-users-delete",
"notifications-email-create",
"notifications-jira-create",
"notifications-jira-view",
"notifications-non_itr_ticket-create",
"notifications-non_itr_ticket-update",
"workspace_dashboard-worksapce-create",
"workspace_dashboard-worksapce-view",
"dashboard-geographic-maps-view",
"dashboard-geographic-report-itr-view",
"configurations-create_alerts-create",
"configurations-notifications-jira-create"
];
I want to create a JSON string from the above array as follows
{
"newsfeeds": {
"alerts": [
{
"name": "view"
}
]
},
"settings": {
"group_details": [
{
"name": "view"
},
{
"name": "edit"
}
],
"privileges": [
{
"name": "view"
},
{
"name": "edit"
}
],
"my_groups": [
{
"name": "view"
},
{
"name": "edit"
},
{
"name": "delete"
}
],
"users": [
{
"name": "view"
},
{
"name": "edit"
},
{
"name": "delete"
}
]
},
"notifications": {
"email": [
{
"name": "create"
}
],
"jira": [
{
"name": "create"
},
{
"name": "view"
}
],
"non_itr_ticket": [
{
"name": "create"
},
{
"name": "update"
}
]
},
"workspace_dashboard": {
"worksapce": [
{
"name": "create"
},
{
"name": "view"
}
]
},
"dashboard": {
"geographic": {
"maps": [
{
"name": "view"
}
],
"report": {
"itr": [
{
"name": "view"
}
]
}
},
"configurations": {
"create_alerts": [
{
"name": "create"
}
],
"notifications": {
"jira": [
{
"name": "create"
}
]
}
}
}
}
The permission array is dynamic. I need to group all common permission under one object.
How to achieve this, any easy methods available ?
Using array.reduce string.split to achieve your desired result
let permissions = ["newsfeeds-alerts-view","settings-group_details-view","settings-group_details-edit","settings-privileges-view","settings-privileges-edit","settings-my_groups-create","settings-my_groups-view","settings-my_groups-edit","settings-my_groups-delete","settings-users-view","settings-users-edit","settings-users-delete","notifications-email-create","notifications-jira-create","notifications-jira-view","notifications-non_itr_ticket-create","notifications-non_itr_ticket-update","workspace_dashboard-worksapce-create","workspace_dashboard-worksapce-view","dashboard-geographic-maps-view","dashboard-geographic-report-itr-view","configurations-create_alerts-create","configurations-notifications-jira-create",];
const output = permissions.reduce((r, s) => {
const path = s.split("-");
if (path.length > 1) {
const name = path.pop();
const last = path.pop();
let destination = r;
for (let key of path) {
destination[key] = destination[key] || {};
destination = destination[key];
}
destination[last] = destination[last] || [];
destination[last].push({ name });
}
return r;
}, {});
console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }
let obj: any = {}
permissions.forEach(permission => {
const [category, subcategory, name] = permission.split('-')
if (!obj[category]) {
obj[category] = {}
}
if (!obj[category][subcategory]) {
obj[category][subcategory] = []
}
obj[category][subcategory].push({ name })
})
let json = JSON.stringify(obj) // there you go
i have an input json object , and i want the below output json from a jquery function . How can i achieve it with min lines of code .
Input
{
"dashboardWidgetFacility": [{
"deskUsageInput": {
"breakup": [{
"location_breakup_0": ["{\"id\":1,\"name\":\"campus\"},{\"id\":8,\"name\":\"building \"}"],
"teams_breakup_0": ["3", "6"]
}, {
"location_breakup_1": ["{\"id\":1,\"name\":\"campus\"},{\"id\":8,\"name\":\"building \"},{\"id\":83,\"name\":\"floor \"}"],
"teams_breakup_1": ["3", "2"]
}]
}
}]
}
Output Object
{
"dashboardWidgetFacility": [{
"campus": {
"id": 1
},
"building": {
"id": 8
},
"widgetInput": {
"deskUsageInput": {
"teams": ["3", "6"]
}
}
}, {
"campus": {
"id": 1
},
"building": {
"id": 8
},
"floor": {
"id": 83
},
"widgetInput": {
"deskUsageInput": {
"teams": ["3", "2"]
}
}
}]
}
Here location breakup location_breakup_{index} , has the index.
I had to correct those location_breakup values because you have to parse out the json, but theyre not technically valid json on their own since theyre missing the square brackets on the sides.
const input = {
dashboardWidgetFacility: [
{
deskUsageInput: {
breakup: [
{
location_breakup_0: [
'{"id":1,"name":"campus"},{"id":8,"name":"building "}',
],
teams_breakup_0: ['3', '6'],
},
{
location_breakup_1: [
'{"id":1,"name":"campus"},{"id":8,"name":"building "},{"id":83,"name":"floor "}',
],
teams_breakup_1: ['3', '2'],
},
],
},
},
],
};
const output = Object.values(
input.dashboardWidgetFacility[0].deskUsageInput.breakup
).reduce(
(acc, item) => {
const nestedItem = Object.keys(item).reduce((acc, key) => {
let locationParsed;
let teamsBreakup;
if (key.startsWith('location_breakup')) {
locationParsed = JSON.parse('[' + item[key] + ']');
}
if (key.startsWith('teams_breakup')) {
teamsBreakup = item[key];
}
const obj = (locationParsed || []).reduce(
(acc, item) => {
const { name, id } = item;
return {
...acc,
[name.trim()]: {
id,
},
};
},
{
widgetInput: {
deskUsageInput: {
teams: null,
},
},
}
);
obj.widgetInput.deskUsageInput.teams = teamsBreakup;
return {
...acc,
...obj,
};
}, {});
return {
dashboardWidgetFacility: [...acc.dashboardWidgetFacility, nestedItem],
};
},
{
dashboardWidgetFacility: [],
}
);
console.log(output);
My question relates to the fact I'm querying 2 different objects from DB and the result is in JSON. I need to merge them into one.
The 2 objects have in common this two key/value IRBId = ... and id = ... and they look as an example
OBJ 1
{
"data":{
"IRBs":{
"nodes":[
{
"id":"8",
"name":"Admin ",
},
{
"id":"9",
"name":"Again",
}
],
}
}
}
OBJ 2
{
"data":{
"informedConsentForms":{
"count":3,
"nodes":[
{
"id":"93",
...
"IRBId":"9",
},
{
"id":"92",
...
"IRBId":"8",
},
{
"id":"91",
...
"IRBId":"8",
}
],
}
},
As you will see above OBJ 2 and OBJ 1 corresponding with the same at IRBid and id.
What I need is to merge the two OBJ where IRBId OBJ 2 === id OBJ 1
The result I would expect after the merge is
OBJ merged
{
[{
"id":"93",
...
"IRBId":"9",
"irb": {
"name":"Again ",
...
}
},
{
"id":"92",
...
"IRBId":"8",
"irb": {
"name":"Admin ",
...
}
},
{
"id":"91",
...
"IRBId":"8",
"irb": {
"name":"Admin ",
...
}
],
},
I don't know how to make it looks like this.
Try using Array.reduce
Logic
Loop through second object data nodes
Find the matching nodes from object 1 data nodes.
Push to accumulator with required details. (I have added only the nodes that was mentioned in in Expected resut, you can add asmuch as you need.)
const obj1 = {
"data": {
"IRBs": {
"nodes": [
{
"id": "8",
"name": "Admin ",
},
{
"id": "9",
"name": "Again",
}
],
}
}
}
const obj2 = {
"data": {
"informedConsentForms": {
"count": 3,
"nodes": [
{
"id": "93",
"IRBId": "9",
},
{
"id": "92",
"IRBId": "8",
},
{
"id": "91",
"IRBId": "8",
}
],
}
},
};
const obj1List = obj1.data.IRBs.nodes;
const output = obj2.data.informedConsentForms.nodes.reduce((acc, curr) => {
const matchingNode = obj1List.find((item) => item.id === curr.IRBId);
if (matchingNode) {
acc.push({
id: curr.id,
IRBId: curr.IRBId,
irb: {
name: matchingNode.name
}
})
}
return acc;
}, []);
console.log(output);
You need to use the map function on the nodes in the first object to construct a new object that contains the second and first object's attributes.
const obj1 = {
"data": {
"IRBs": {
"nodes": [{
"id": "8",
"obj1": "one",
"name": "Admin ",
},
{
"id": "9",
"obj1": "two",
"name": "Again",
}
]
}
}
};
const obj2 = {
"data": {
"informedConsentForms": {
"count": 3,
"nodes": [{
"id": "93",
"obj2": "1",
"IRBId": "9",
},
{
"id": "92",
"obj2": "2",
"IRBId": "8",
},
{
"id": "91",
"obj2": "3",
"IRBId": "8",
}
],
}
}
};
const obj1Data = obj1.data.IRBs.nodes;
const obj2Data = obj2.data.informedConsentForms.nodes;
const res = obj2Data.map(item => {
const obj1Item = obj1Data.find(obj1Item => item.IRBId === obj1Item.id);
return obj1Item ? { ...item, "irb": { ...obj1Item}} : { ...item};
});
console.log(res);
i am using nested loop, try this one
const obj2 = {
"data":{
"informedConsentForms":{
"count":3,
"nodes":[
{
"id":"93",
"IRBId":"9",
},
{
"id":"92",
"IRBId":"8",
},
{
"id":"91",
"IRBId":"8",
}
],
}
},
}
const obj1 = {
"data":{
"IRBs":{
"nodes":[
{
"id":"8",
"name":"Admin ",
},
{
"id":"9",
"name":"Again",
}
],
}
}
}
const result = [];
const obj2Nodes = obj2.data.informedConsentForms.nodes;
for(let i = 0; i < obj2Nodes.length; i++) {
const obj1Nodes = obj1.data.IRBs.nodes
for(let j = 0; j < obj1Nodes.length; j++) {
if(obj2Nodes[i].IRBId === obj1Nodes[j].id) {
const {id, ...reObj1Nodes} = obj1Nodes[j];
result.push({
...obj2Nodes[i],
'irb': {
...reObj1Nodes
}
})
}
}
}
console.log(result)
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
Another Recursive Function I have tried:
handleRecursiveParentChildNode(parent: CurrentTopicMetadataTreeNode, searchKey) {
let result = parent;
result.children = [];
if (parent.children.length > 0) {
parent.children.forEach(child => {
let childData = this.handleRecursiveParentChildNode(child, searchKey);
if (childData.data && childData.data != undefined)
result.children.push(childData);
});
let cate = parent.data.metadata.category.filter(cat => cat === searchKey);
if (!result.children && cate.length < 1) {
result = null;
}
}
else {
let cate = parent.data.metadata.category.filter(cat => cat === searchKey);
if (cate.length < 1) {
result = null;
}
}
return result;
}
You can filter the data with Array.prototype.filter
const data = [{"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":[]}]}]
const dfs = (iNode, type) => {
const node = Object.assign({}, iNode) // shallow copy current node
node.children = iNode.children.flatMap(child => {
// if child matches type, return it, otherwise filter it out
return child.data.metadata.category.includes(type) ? dfs(child, type) : []
})
return node
}
// fakes a root node to apply dfs on
const cspList = dfs({ children: data }, 'Csp').children
console.log(JSON.stringify(cspList, null, 2))
edit: in case flatMap can't be used (for some reasons) it is possible to use filter + map
const data = [{"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":[]}]}]
const dfs = (iNode, type) => {
const node = Object.assign({}, iNode) // shallow copy current node
node.children = iNode.children
.filter(child => child.data.metadata.category.includes(type))
.map(child => dfs(child, type))
return node
}
// fakes a root node to apply dfs on
const cspList = dfs({ children: data }, 'Csp').children
console.log(JSON.stringify(cspList, null, 2))
regarding errors in original code
handleRecursiveParentChildNode(parent: CurrentTopicMetadataTreeNode, searchKey) {
let result = parent;
result.children = [];
// bug? since we are called from parent we obviously are a children
// so else block is never run
if (parent.children.length > 0) {
parent.children.forEach(child => {
let childData = this.handleRecursiveParentChildNode(child, searchKey);
// bug ? we never filter out children and push every one of them on result
if (childData.data && childData.data != undefined)
result.children.push(childData);
});
// bug ? !result.children is never truthy (![] === false)
// so if is never run
let cate = parent.data.metadata.category.filter(cat => cat === searchKey);
if (!result.children && cate.length < 1) {
result = null;
}
}
// never run
else {
let cate = parent.data.metadata.category.filter(cat => cat === searchKey);
if (cate.length < 1) {
result = null;
}
}
return result;
}
You can use recursive call reduce for filter your data:
const filterItems = (items, f) => {
const fitems = items.reduce((acc, rec) => {
const children = rec.children.length > 0 ? filterItems(rec.children, f): []
if (rec.data.metadata.category.indexOf(f) >= 0) {
return [...acc, {...rec, children}]
}
return [...acc]
}, [])
return fitems
}
I do have a json array object. I need to modify it then save the modified version on a variable.
the json object
var json = [
{
"Name": "March-2016",
"Elements": [
{
"Name": "aa",
"Elements": [
{
"Name": "ss",
"Data": {
"Test1": [
22
],
"Test2": [
33
],
"Test3": [
44
],
"Test4": [
55
]
}
},
{
"Name": "ssee",
"Data": {
"Test12": [
222
],
"Test22": [
3322
],
"Test32": [
445
],
"Test42": [
553
]
}
}
]
}
]
}
];
need to be modified to
var json = [
{
"Name": "March-2016",
"Elements": [
{
"Name": "aa",
"Elements": [
{
"category": "ss",
"Test1": 22,
"Test2": 33 ,
"Test3":44,
"Test4": 55
},
{
"category": "ssee",
"Test12": 222,
"Test22": 3322 ,
"Test32":445,
"Test42": 553
}
]
}
]
}
];
I have this method but its not doing the job
var saveJson = function(arr) {
var nameValuePairs = [];
for (var i = 0, len = arr.length; i < len; i++) {
var item = arr[i];
if (item.Data) {
var newvar = {
category : item.Name
}
newvar[Object.keys(item.Data)] = Object.values(item.Data);
item = newvar
}
if (item.Elements) {
nameValuePairs = nameValuePairs.concat(saveJson(item.Elements));
}
}
return arr;
};
I need this conversion to be dynamic as for sure I will get bigger json than the posted one
sorry for the confusion and thanks in advance.
The original object is really a mess, but still you just need to step through it and pull out the values you want. This changes the json object in place:
json.forEach(item => {
item.Elements.forEach(Outer_El => {
Outer_El.Elements = Outer_El.Elements.map(item =>{
let obj = {category: item.Name}
Object.keys(item.Data).forEach(key => {
obj[key] = item.Data[key][0]
})
return obj
})
})
})
json should now look like:
[{
"Name":"March-2016",
"Elements":[
{
"Name":"aa",
"Elements":[
{
"category":"ss",
"Test1":22,
"Test2":33,
"Test3":44,
"Test4":55
},
{
"category":"ssee",
"Test1e":224,
"Test2e":334,
"Test3e":443,
"Test4e":554
}
]
}
]
}]
You can use destructuring assignment to get specific property values from an object
{
let {Name:categories, Data:{Test:[Test]}} = json[0].Elements[0].Elements[0];
json[0].Elements[0].Elements[0] = {categories, Test};
}