Issue
I am trying to push the Id, typography and active and converting the nested one to flat JSON to use ReactDND npm library
I have JSON like this
[
{
"menuHead":[
{
"name":"MenuHead 01",
"description":"sample Head 01",
"icon":"sample01.png",
"products":[
{
"name":"product 01",
"description":"sample product ONE",
"icon":"product01.png",
"section":[
{
"name":"section01",
"description":"ActiveLayer",
"icon":"img.png",
"min":100,
"max":1000,
},
{
"name":"section02",
"description":"ActiveLayer",
"icon":"img.png",
"min":500,
"max":1000,
},
{
"name":"section03",
"description":"ActiveLayer",
"icon":"img.png",
"min":100,
"max":600,
}
]
}
]
}
]
}
]
I want push Id, typography and active as boolean to the array of objects and I want convert the JSON to Flat JSON as well (I want sections - typography to be same and Menu head, products typography to be different, similarly sections should have active as false and others as true)
I want output like this
[
{
"name":"MenuHead 01",
"description":"sample Head 01",
"icon":"sample01.png",
"id":1,
"typography":0,
"active":true,
},
{
"name":"product 01",
"description":"sample product ONE",
"icon":"product01.png",
"id":2,
"typography":1,
"active":true,
},
{
"name":"section01",
"description":"ActiveLayer",
"icon":"img.png",
"min":100,
"max":1000,
"id":4,
"typography":2,
"active":false,
},
{
"name":"section03",
"description":"ActiveLayer",
"icon":"img.png",
"min":100,
"max":600,
"id":5,
"typography":2,
"active":false,
},
{
"name":"section03",
"description":"ActiveLayer",
"icon":"img.png",
"min":100,
"max":600,
"id":6,
"typography":2,
"active":false,
}
]
I have tried this I am getting error and I want don't want to mention key example (obj.menuHead, obj.products, obj.sections)since the name will be changed later something like recursive way
const tree = [
{
"menuHead":[
{
"name":"MenuHead 01",
"description":"sample Head 01",
"icon":"sample01.png",
"products":[
{
"name":"product 01",
"description":"sample product ONE",
"icon":"product01.png",
"sections":[
{
"name":"section01",
"description":"ActiveLayer",
"icon":"img.png",
"min":100,
"max":1000,
},
{
"name":"section02",
"description":"ActiveLayer",
"icon":"img.png",
"min":500,
"max":1000,
},
{
"name":"section03",
"description":"ActiveLayer",
"icon":"img.png",
"min":100,
"max":600,
}
]
}
]
}
]
}
]
function addUniqueID(arr: any[], i: number) {
arr.forEach((obj) => {
obj.typography = i;
obj.id = i + 1;
obj.active = true;
if (obj.menuHead) {
addUniqueID(obj.menuHead, i + 1);
}
else if (obj.sections) {
addUniqueID(obj.sections, i + 1);
}
else if (obj.products) {
addUniqueID(obj.products, i + 1);
} else {
obj.active = false;
}
});
}
addUniqueID(tree, 0);
console.log(tree)
const c = (item: any) => "name" in item ? [{
name: item.name,
id: item.id,
typography: item.typography,
active: item.active,
description:item.description,
icon: item.icon,
min:item.min,
max:item.max
}] : []
function flat(item: any) {
if ("products" in item) {
return c(item).concat(item.products.flatMap(flat))
}
if ("sections" in item) {
return c(item).concat(item.sections.flatMap(flat))
}
return (
c(item)
)
}
console.log(JSON.stringify (tree.flatMap(flat)))
Solution
DYNAMIC KEYS
You can try to use recursion for all data key loopings which is helpful in dynamic keys.
const data = [{
"menuHead": [{
"name": "MenuHead 01",
"description": "sample Head 01",
"icon": "sample01.png",
"products": [{
"name": "product 01",
"description": "sample product ONE",
"icon": "product01.png",
"section": [{
"name": "section01",
"description": "ActiveLayer",
"icon": "img.png",
"min": 100,
"max": 1000,
},
{
"name": "section02",
"description": "ActiveLayer",
"icon": "img.png",
"min": 500,
"max": 1000,
},
{
"name": "section03",
"description": "ActiveLayer",
"icon": "img.png",
"min": 100,
"max": 600,
}
]
}]
}]
}]
function populateMenuItems(currentSet, typographyValue = -1, result = []) {
for (const item of currentSet) {
const itemKeys = Object.keys(item)
const newItem = {
typography: typographyValue,
active: typographyValue < 2,
}
for (const itemKey of itemKeys) {
if (Array.isArray(item[itemKey])) {
populateMenuItems(item[itemKey], typographyValue + 1, result)
} else {
newItem[itemKey] = item[itemKey]
}
}
if (typographyValue >= 0) {
result.push(newItem)
}
}
return result.sort((a, b) => a.typography - b.typography).map((item, index) => ({ ...item, id: index + 1 }))
}
const finalResult = populateMenuItems(data)
console.log(finalResult)
STATIC KEYS
You also can try this approach with reduce
and looping through products
and section
for the new array population.
Note that I'm using currentId
for tracking id changes. You can get the final result with finalResult.items
.
const data = [{
"menuHead": [{
"name": "MenuHead 01",
"description": "sample Head 01",
"icon": "sample01.png",
"products": [{
"name": "product 01",
"description": "sample product ONE",
"icon": "product01.png",
"section": [{
"name": "section01",
"description": "ActiveLayer",
"icon": "img.png",
"min": 100,
"max": 1000,
},
{
"name": "section02",
"description": "ActiveLayer",
"icon": "img.png",
"min": 500,
"max": 1000,
},
{
"name": "section03",
"description": "ActiveLayer",
"icon": "img.png",
"min": 100,
"max": 600,
}
]
}]
}]
}]
const finalResult = data.reduce((result, current) => {
if (!current.menuHead) {
return result
}
for (const menuHeadItem of current.menuHead) {
const {
products,
...others
} = menuHeadItem
result.items.push({
...others,
typography: 0,
active: true,
id: result.currentId
})
result.currentId++
if (!products) {
continue
}
for (const product of products) {
const {
section,
...others
} = product
result.items.push({
...others,
typography: 1,
active: true,
id: result.currentId
})
result.currentId++
for (const sectionItem of section) {
result.items.push({
...sectionItem,
typography: 2,
active: false,
id: result.currentId
})
result.currentId++
}
}
}
return result
}, {
currentId: 1,
items: []
})
console.log(finalResult.items)
Answered By - Nick Vu
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.