how to properly use recursive function to go through multiple nested objects - javascript

In my Angular app, I'm using AngularTree directive (http://wix.github.io/angular-tree-control) to render a tree view of the following data structure, as shown in https://jsfiddle.net/eugene_goldberg/Lvwxx629/17/:
$scope.subjectAreas = [
{
name: "Area-1",
link: "dashboards.dashboard_1",
entities: [
{
name: "entity 1"
},
{
name: "entity 2"
}
],
offerings: [
{
name: "offering 1"
},
{
name: "offering 2"
}
]
},
{
name: "Area-2",
link: "dashboards.dashboard_1",
entities: [
{
name: "entity 3"
}
],
offerings: [
{
name: "offering 3"
}
]
},
{
name: "Area-3",
link: "dashboards.dashboard_1",
entities: [
{
name: "entity 4"
},
{
name: "entity 5"
},
{
name: "entity 6"
}
],
offerings: [
{
name: "offering 4"
},
{
name: "offering 5"
}
]
}
];
This treeView directive provides the "createSubTree" function, which I'm using as follows:
function createSubTree(ary) {
var res = [];
if (ary) {
res = ary.map(function(v, k) {
var id = k + 1;
return {
i: id,
id: 'id' + id,
label: v.name,
children: createSubTree(v.entities)
}
});
}
return res;
}
$scope.treedata = createSubTree($scope.subjectAreas);
The output looks like this:
Area-1
entity-1
entity-2
Area-2
entity-3
Area-3
entity-4
entity-5
entity-6
As my data structure contains two nested arrays for each SubjectArea (entities, and offerings), I need to have a sub-folder for entities, and a sub-folder for offerings as children of each SubjectArea, so the output should look like this:
Area-1
entities
entity-1
entity-2
offerings
offering-1
offering-2
Area-2
entities
entity-3
offerings
offering-3
Area-3
entities
entity-4
entity-5
entity-6
offerings
offering-4
offering-5
How can I modify the current code to have the recursive function create sub-groups for both entities and offerings?

Change your data to this:
$scope.subjectAreas = [{
name: "Area-1",
link: "dashboards.dashboard_1",
entities: [{
name: 'entities',
entities: [{
name: "entity 1"
}, {
name: "entity 2"
}]
}, {
name: 'offerings',
entities: [{
name: "offering 1"
}, {
name: "offering 2"
}]
}]
}, {
name: "Area-2",
link: "dashboards.dashboard_1",
entities: [{
name: "entity 3"
}],
offerings: [{
name: "offering 3"
}]
}, {
name: "Area-3",
link: "dashboards.dashboard_1",
entities: [{
name: "entity 4"
}, {
name: "entity 5"
}, {
name: "entity 6"
}],
offerings: [{
name: "offering 4"
}, {
name: "offering 5"
}]
}];
I've only done the first part, but you can complete the rest.

Related

How do I create arrays from array in this case

I am trying to create multiple arrays of objects with each keys inside the object.
How can I generate my expected output (shown below the initial array)?
Initial array:
[{
title: 'Linus tech tips',
name: 'Linus',
id: 'SA946',
},
{
title: 'Linus tech tips',
name: 'Colton',
id: 'SA947',
}
];
Expected output:
[{
text: 'Linus tech tips',
}, {
text: 'Linus',
}, {
text: 'SA946',
}, ],
[{
text: 'Linus tech tips',
}, {
text: 'Colton',
}, {
text: 'SA947',
}, ],
You can use array.map to achieve that. Please have a look:
const initial = [
{
title: 'Linus tech tips',
name: 'Linus',
id: 'SA946',
},
{
title: 'Linus tech tips',
name: 'Colton',
id: 'SA947',
},
];
const expected = initial.map(
(item) => Object.values(item).map(
(itemValue) => ({ text: itemValue }),
),
);
console.log(expected);
You need to iterate over the keys, then flatten the array.
[{
title: 'Linus tech tips',
name: 'Linus',
id: 'SA946',
},
{
title: 'Linus tech tips',
name: 'Colton',
id: 'SA947',
}].map(
item => {
return Object.keys(item).map(
key => {
return {text: item[key]}
}
)
}
).flat()
[
{
"text": "Linus tech tips"
},
{
"text": "Linus"
},
{
"text": "SA946"
},
{
"text": "Linus tech tips"
},
{
"text": "Colton"
},
{
"text": "SA947"
}
]
Or, if you want to have the items separated, do not use flat() at the end:
[
[
{
"text": "Linus tech tips"
},
{
"text": "Linus"
},
{
"text": "SA946"
}
],
[
{
"text": "Linus tech tips"
},
{
"text": "Colton"
},
{
"text": "SA947"
}
]
]

Mapping array in javacript app in a react app

This is my array, I'm working on react app
const categoryObj = [
{
id: "463e989a-c4f2-4616-85c5-0cb610c5fff0",
name: "Women",
subCategory: [
{
id: "91ba7308-b68e-4d0c-85d8-0cc8272c6bc8",
name: "All",
icon: "AllIcon"
},
{
id: "0e0712c5-0b5a-4d4e-acf5-3d7faf2caa2a",
name: "Clothes",
icon: "ClothesIcon",
sections: [
{
id: "9b7a7a58-04a1-4aba-ba68-0e6b1390021e",
name: "All",
href: "Women/Clothes/All".split(' ').join('-').trim().toLowerCase()
}
]
}
]
}
]
how can I access "women" in this array ? (I have many items like "women" this is just a sample of a large array. if you can suggest a mapping method it's better.)
You can map through it to get the name value in this way:
categoryObj.map((category) => category.name)
const categoryObj = [
{
id: "463e989a-c4f2-4616-85c5-0cb610c5fff0",
name: "Women",
subCategory: [
{
id: "91ba7308-b68e-4d0c-85d8-0cc8272c6bc8",
name: "All",
icon: "AllIcon"
},
{
id: "0e0712c5-0b5a-4d4e-acf5-3d7faf2caa2a",
name: "Clothes",
icon: "ClothesIcon",
sections: [
{
id: "9b7a7a58-04a1-4aba-ba68-0e6b1390021e",
name: "All",
href: "Women/Clothes/All".split(' ').join('-').trim().toLowerCase()
}
]
}
]
},
{
id: "463e989a-c4f2-4616-85c5-0cb610c5fff0",
name: "Men",
subCategory: [
{
id: "91ba7308-b68e-4d0c-85d8-0cc8272c6bc8",
name: "All",
icon: "AllIcon"
},
{
id: "0e0712c5-0b5a-4d4e-acf5-3d7faf2caa2a",
name: "Clothes",
icon: "ClothesIcon",
sections: [
{
id: "9b7a7a58-04a1-4aba-ba68-0e6b1390021e",
name: "All",
href: "Women/Clothes/All".split(' ').join('-').trim().toLowerCase()
}
]
}
]
},
{
id: "463e989a-c4f2-4616-85c5-0cb610c5fff0",
name: "Children",
subCategory: [
{
id: "91ba7308-b68e-4d0c-85d8-0cc8272c6bc8",
name: "All",
icon: "AllIcon"
},
{
id: "0e0712c5-0b5a-4d4e-acf5-3d7faf2caa2a",
name: "Clothes",
icon: "ClothesIcon",
sections: [
{
id: "9b7a7a58-04a1-4aba-ba68-0e6b1390021e",
name: "All",
href: "Women/Clothes/All".split(' ').join('-').trim().toLowerCase()
}
]
}
]
}
]
const result = categoryObj.filter(obj => obj.name === 'Women')
console.log('multi objects :', result)
// if unique with name
const resultUnique = categoryObj.find(obj => obj.name === 'Women')
console.log('unique object :', resultUnique)
This object contains an object and have another variations as sub. If you want to access first name,
categoryObj.map((it) => {
//You can handle it like this
console.log(it.name)
})
But if you want all name of all subCategory,
categoryObj[0].subCategory.map((cat) => {
//You can handle it like this
console.log(cat.name)
})
You have same object-type in and out.
const res = categoryObj.filter(item=>item.name === 'Women');

Add field to each object of an array based on other field

I have the following Array of data:
{
_id: 5f5726ef7d475a61a95c5e0c,
attributes: [
{
values: [
{ name: '1' }
],
},
{
values: [
{ name: '2' }
]
}
],
attr1: [
{ name: "Study Code" },
{ name: "Patient Study" }
]
}
What I need is to add the correspondent value to each on of attr1 objects based on index. So the result would be:
{
_id: 5f5726ef7d475a61a95c5e0c,
attributes: [
{
values: [
{ name: '1' }
],
},
{
values: [
{ name: '2' }
]
},
],
attr1: [
{
name: "Study Code",
values: [{ name: "1" }]
},
{
name: "Patient Study",
values: [{ name: "2" }]
}
],
}
I wonder if that possible using aggregation $addFields in MongoDB
Query
query works if arrays same size
ziparray to make [[member1_1 member2_1], ....]
map to merge member1_1,member2_1 to a document
Playmongo
aggregate(
[{"$set": {"attr1": {"$zip": {"inputs": ["$attributes", "$attr1"]}}}},
{"$set":
{"attr1":
{"$map":
{"input": "$attr1",
"in":
{"$mergeObjects":
[{"$arrayElemAt": ["$$this", 1]},
{"$arrayElemAt": ["$$this", 0]}]}}}}}])
You can use $zip
db.collection.aggregate([
{
"$project": {
attributes: {
"$zip": {
"inputs": [
"$attributes",
"$attr1"
]
}
}
}
}
])
Here is the Mongo playground for your reference.

How to get the tooltip for the element with no children in d3.js

In D3.js layout , the tooltip is visible only for the nodes which has children .
Find my code attached
https://codesandbox.io/s/affectionate-thunder-l024x
I have an object some of them contains children , some are not . While displaying them in the chart , the tooltip only visible to the object which has children in it .
const dataObj = {
name: "Home",
children: [
{
name: "A",
metricsValue: "ma",
children: [
{
name: "A-B",
value: 1.2,
metricsValue: "ma-mb"
},
{
name: "A-B-C",
metricsValue: "ma-mb-mc",
children: [
{
name: "A-B-C-D-1",
value: 2.5,
metricsValue: "ma-mb-mc-md-1"
},
{
name: "A-B-C-D-2",
value: 2.566,
metricsValue: "ma-mb-mc-md-2"
}
]
}
]
},
{
name: "BCD",
value: "6.5",
metricsValue: "m1"
}
]
};

Nested keys in mustache template

I have following data structure:
var data = {
labels: { name: "Name" },
data: {
name: "Layer 1",
children: [
{
name: "Layer 1-1",
children: [
{ name: "Layer 1-1-1" },
{ name: "Layer 1-1-2" }
]
},
{
name: "Layer 1-2",
children: [
{ name: "Layer 1-2-1" },
{ name: "Layer 1-2-2" }
]
},
{ name: "Layer 1-3" }
]
}
};
As you can see each layer can have it's own children. In this fiddle you can see, that the children are rendered multiple times: https://jsfiddle.net/kaljak/9xuLpnxp/
What do I have to change that the children are only rendered once?
You have one to many {{#children}} tags, you should change the upper one to {{#data}}
See this fiddle: https://jsfiddle.net/9xuLpnxp/1/

Categories

Resources