如何过滤复杂的JSON结构



我有以下JSON数据:

{
"data": {
"event": {
"eventId": "599df9a8-efdd-440f-936b-a4cab9100988",
"name": "abc",
"eventOrder": {
"menuItemIds": [
{
"menuId": "130c4d6a-ba3c-43fc-917c-17090b26a36e",
"menuItemId": "422ec16c-c9c0-4c3d-a974-021dab39e563",
"quantity": 5
},
{
"menuId": "de6368d5-a076-4058-8f93-a0bac39bb451",
"menuItemId": "945dafd8-bf01-4a51-b6c8-a4c863db5d1f",
"quantity": 4
},
{
"menuId": "966a7ec0-5ef4-4514-bd10-0043fbca982c",
"menuItemId": "c042f13b-b49f-4164-8817-c6a9623c7c40",
"quantity": 6
},
{
"menuId": "966a7ec0-5ef4-4514-bd10-0043fbca982c",
"menuItemId": "1f2b92b6-8a4d-403f-bbf8-92ef2bc0b34b",
"quantity": 2
},
{
"menuId": "966a7ec0-5ef4-4514-bd10-0043fbca982c",
"menuItemId": "a6697045-5c3d-4473-a434-c0674b8f4af2",
"quantity": 1
}
],
"menus": [
{
"menuId": "de6368d5-a076-4058-8f93-a0bac39bb451",
"name": "Canapé Two",
"category": "FOOD",
"menuSections": [
{
"name": "Package ",
"menuSectionItems": [
{
"itemId": "945dafd8-bf01-4a51-b6c8-a4c863db5d1f",
"name": "Canapé Two"
}
]
}
]
},
{
"menuId": "130c4d6a-ba3c-43fc-917c-17090b26a36e",
"name": "Canapé One ",
"category": "FOOD",
"menuSections": [
{
"name": "Package ",
"menuSectionItems": [
{
"itemId": "422ec16c-c9c0-4c3d-a974-021dab39e563",
"name": "Canapé One "
}
]
}
]
},
{
"menuId": "966a7ec0-5ef4-4514-bd10-0043fbca982c",
"name": "Package Two ",
"category": "DRINK",
"menuSections": [
{
"name": "Packages ",
"menuSectionItems": [
{
"itemId": "c042f13b-b49f-4164-8817-c6a9623c7c40",
"name": "Package Two - 2 Hours "
},
{
"itemId": "1f2b92b6-8a4d-403f-bbf8-92ef2bc0b34b",
"name": "Package Two - 3 Hours "
},
{
"itemId": "a6697045-5c3d-4473-a434-c0674b8f4af2",
"name": "Package Two - 4 Hours "
}
]
}
]
}
]
}
}
}
}

JSON表示食物/饮料菜单。

menus是一个包含所有菜单的对象数组,让我们以第一个对象为例。菜单的名称是Canape Two,它位于名为Package的部分下,该部分名称存在于menuSections下,一个菜单可能存在于多个部分下。

menuSectionItems还包含菜单内的菜单项列表,该列表也可能包含子项本身。

我们还有menuItemIds,它包含菜单中某个项目的数量。

我想做的是以以下形式显示数据:

* SECTION NAME
* MENU NAME
* ITEM NAME    QTY: X
* SUB-ITEM NAME

基于我上面提供的JSON,结果应该是:

* Package
* Canape Two
* Canape Two    QTY: 4
* (No Sub-Item, So Blank)
* Canape One
* Canape One    QTY: 5
* (No Sub-Item, So Blank)
* Packages
* Package Two
* Package Two - 2 Hours    QTY: 6
* (No Sub-Item, So Blank)
* Package Two - 3 Hours    QTY: 2
* (No Sub-Item, So Blank)
* Package Two - 4 Hours    QTY: 1
* (No Sub-Item, So Blank)

我不知道如何过滤数据,我很乐意得到你的帮助。我还将使用React将数据作为列表呈现到用户界面。

假设menuSections数组总是只包含一个元素,则可以开始将数据拆分为两个数组:

  • menuItemIds
  • menu

然后,对于menuItemIds中的每个id,您可以在menus数组上使用find()来获得menu元素和menuItem元素。

一旦你得到了所有这些,你就可以构建一个根据你的需求格式化的结果对象:

const data = {
"data": {
"event": {
"eventId": "599df9a8-efdd-440f-936b-a4cab9100988",
"name": "abc",
"eventOrder": {
"menuItemIds": [{
"menuId": "130c4d6a-ba3c-43fc-917c-17090b26a36e",
"menuItemId": "422ec16c-c9c0-4c3d-a974-021dab39e563",
"quantity": 5
},
{
"menuId": "de6368d5-a076-4058-8f93-a0bac39bb451",
"menuItemId": "945dafd8-bf01-4a51-b6c8-a4c863db5d1f",
"quantity": 4
},
{
"menuId": "966a7ec0-5ef4-4514-bd10-0043fbca982c",
"menuItemId": "c042f13b-b49f-4164-8817-c6a9623c7c40",
"quantity": 6
},
{
"menuId": "966a7ec0-5ef4-4514-bd10-0043fbca982c",
"menuItemId": "1f2b92b6-8a4d-403f-bbf8-92ef2bc0b34b",
"quantity": 2
},
{
"menuId": "966a7ec0-5ef4-4514-bd10-0043fbca982c",
"menuItemId": "a6697045-5c3d-4473-a434-c0674b8f4af2",
"quantity": 1
}
],
"menus": [{
"menuId": "de6368d5-a076-4058-8f93-a0bac39bb451",
"name": "Canapé Two",
"category": "FOOD",
"menuSections": [{
"name": "Package ",
"menuSectionItems": [{
"itemId": "945dafd8-bf01-4a51-b6c8-a4c863db5d1f",
"name": "Canapé Two"
}]
}]
},
{
"menuId": "130c4d6a-ba3c-43fc-917c-17090b26a36e",
"name": "Canapé One ",
"category": "FOOD",
"menuSections": [{
"name": "Package ",
"menuSectionItems": [{
"itemId": "422ec16c-c9c0-4c3d-a974-021dab39e563",
"name": "Canapé One "
}]
}]
},
{
"menuId": "966a7ec0-5ef4-4514-bd10-0043fbca982c",
"name": "Package Two ",
"category": "DRINK",
"menuSections": [{
"name": "Packages ",
"menuSectionItems": [{
"itemId": "c042f13b-b49f-4164-8817-c6a9623c7c40",
"name": "Package Two - 2 Hours "
},
{
"itemId": "1f2b92b6-8a4d-403f-bbf8-92ef2bc0b34b",
"name": "Package Two - 3 Hours "
},
{
"itemId": "a6697045-5c3d-4473-a434-c0674b8f4af2",
"name": "Package Two - 4 Hours "
}
]
}]
}
]
}
}
}
}

const menuItemIds = data.data.event.eventOrder.menuItemIds
const menus = data.data.event.eventOrder.menus
const resObj = {}
for (const item of menuItemIds) {
const menuId = item.menuId
const menuItemId = item.menuItemId
const quantity = item.quantity
const theMenu = menus.find(m => m.menuId === menuId)
const theSectionItem = theMenu.menuSections[0].menuSectionItems.find(m => m.itemId === menuItemId)
if (resObj.hasOwnProperty(theMenu.menuSections[0].name)) {
resObj[theMenu.menuSections[0].name].push({
menuName: theMenu.name,
menuSectionItemName: theSectionItem.name,
menuSectionItemQty: quantity
})
} else {
resObj[theMenu.menuSections[0].name] = []
resObj[theMenu.menuSections[0].name].push({
menuName: theMenu.name,
menuSectionItemName: theSectionItem.name,
menuSectionItemQty: quantity
})
}
}
console.log(resObj)

在给出示例之前,我们暂时不考虑子项。然后剩下的就是按节、菜单和项目进行分组。

为了将其打印为列表,我们将重复使用一些内容。

var input = {data:{event:{eventId:"599df9a8-efdd-440f-936b-a4cab9100988",name:"abc",eventOrder:{menuItemIds:[{menuId:"130c4d6a-ba3c-43fc-917c-17090b26a36e",menuItemId:"422ec16c-c9c0-4c3d-a974-021dab39e563",quantity:5},{menuId:"de6368d5-a076-4058-8f93-a0bac39bb451",menuItemId:"945dafd8-bf01-4a51-b6c8-a4c863db5d1f",quantity:4},{menuId:"966a7ec0-5ef4-4514-bd10-0043fbca982c",menuItemId:"c042f13b-b49f-4164-8817-c6a9623c7c40",quantity:6},{menuId:"966a7ec0-5ef4-4514-bd10-0043fbca982c",menuItemId:"1f2b92b6-8a4d-403f-bbf8-92ef2bc0b34b",quantity:2},{menuId:"966a7ec0-5ef4-4514-bd10-0043fbca982c",menuItemId:"a6697045-5c3d-4473-a434-c0674b8f4af2",quantity:1}],menus:[{menuId:"de6368d5-a076-4058-8f93-a0bac39bb451",name:"Canapxe9 Two",category:"FOOD",menuSections:[{name:"Package ",menuSectionItems:[{itemId:"945dafd8-bf01-4a51-b6c8-a4c863db5d1f",name:"Canapxe9 Two"}]}]},{menuId:"130c4d6a-ba3c-43fc-917c-17090b26a36e",name:"Canapxe9 One ",category:"FOOD",menuSections:[{name:"Package ",menuSectionItems:[{itemId:"422ec16c-c9c0-4c3d-a974-021dab39e563",name:"Canapxe9 One "}]}]},{menuId:"966a7ec0-5ef4-4514-bd10-0043fbca982c",name:"Package Two ",category:"DRINK",menuSections:[{name:"Packages ",menuSectionItems:[{itemId:"c042f13b-b49f-4164-8817-c6a9623c7c40",name:"Package Two - 2 Hours "},{itemId:"1f2b92b6-8a4d-403f-bbf8-92ef2bc0b34b",name:"Package Two - 3 Hours "},{itemId:"a6697045-5c3d-4473-a434-c0674b8f4af2",name:"Package Two - 4 Hours "}]}]}]}}}};
var menus = input.data.event.eventOrder.menus
var menuItemIds = input.data.event.eventOrder.menuItemIds
var obj = menus.reduce(function(agg, menu) {
menu.menuSections.forEach(function(menu_section) {
agg[menu_section.name] ??=  {}
agg[menu_section.name][menu.name] ??= {}
menu_section.menuSectionItems.forEach(function(section_item) {

var find = menuItemIds.find(item => item.menuItemId === section_item.itemId)
agg[menu_section.name][menu.name][section_item.name] ??= {}
agg[menu_section.name][menu.name][section_item.name].QTY = find.quantity
// same idea for sub items i guess
})
})
return agg;
}, {})

function treeView(tree) {
var markup = '';
Object.keys(tree).forEach(function(key) {
var value = tree[key];
markup += '<li>' + (typeof (value)==='object' ? key + treeView(value) : value) + '</li>';

})
return "<ul>" + markup + "</ul>";
}
// console.log(obj)
document.querySelector("#output").innerHTML = treeView(obj)
.as-console-wrapper {
max-height: 100% !important
}
<div id="output"></div>

最新更新