使用 Javascript 根据深度值过滤嵌套对象
Posted
技术标签:
【中文标题】使用 Javascript 根据深度值过滤嵌套对象【英文标题】:Filter nested object based on deep value with Javascript 【发布时间】:2022-01-20 19:15:57 【问题描述】:我有这个嵌套对象:
const menus =
path: '/actions/step',
icon: 'fa fa-wine-bottle',
title: 'Fasi',
children: [
path: '/actions/step/analysis',
title: 'Analisi'
,
path: '/actions/step/import',
title: 'Importazione'
,
path: '/actions/step/squeeze',
title: 'Spremitura'
,
path: '/actions/step/move',
title: 'Spostamento'
,
path: '/actions/step/splitauto',
title: 'Travaso Guidato'
,
path: '/actions/step/stir',
title: 'Rimestaggio'
,
path: '/actions/step/clarify',
title: 'Chiarifica'
,
path: '/actions/step/stabilization',
title: 'Stabilizzazione'
,
path: '/actions/step/bottling',
title: 'Imbottigliamento'
,
path: '/actions/step/clean',
title: 'Pulizia'
,
path: '/actions/step/clean_close',
title: 'Pulizia e Chiusura'
,
path: '/actions/step/add_product',
title: 'Aggiunta Prodotto'
,
]
,
path: '/actions',
icon: 'fa fa-tasks',
title: 'Azioni',
children: [
path: '/actions/type',
title: 'Tipi di Azione'
,
path: '/actions/list',
title: 'Lista delle Azioni'
,
path: '/actions/traceability',
title: 'Tracciabilità'
]
,
path: '/warehouse',
icon: 'fa fa-warehouse',
title: 'Magazzino',
children: [
path: '/warehouse/list-warehouse-item',
title: 'Lista Oggetti',
children: [
path: '/warehouse/new-warehouse-item',
title: 'Nuovo Oggetto'
]
,
]
,
path: '/suppliers',
icon: 'fa fa-truck',
title: 'Fornitori',
children: [
path: '/suppliers/list-suppliers',
title: 'Lista Fornitori',
children: [
path: '/suppliers/new-supplier',
title: 'Nuovo Fornitore'
]
]
我想要实现的是根据路径值过滤嵌套对象。
如果我有/actions/step/import
,我想拥有这个:
[
path: '/actions/step',
icon: 'fa fa-wine-bottle',
title: 'Fasi'
,
path: '/actions/step/import',
title: 'Importazione'
]
或者如果/warehouse/new-warehouse-item
我会:
[
path: '/warehouse',
icon: 'fa fa-warehouse',
title: 'Magazzino'
,
path: '/warehouse/list-warehouse-item',
title: 'Lista Oggetti'
,
path: '/warehouse/new-warehouse-item',
title: 'Nuovo Oggetto'
]
我试图做的是像这样过滤,但它不完整(this.$router.history.current.path
包含字符串路径):
menus.filter(menu =>
if(menu.children)
return menu.children.some(child =>
if(child.children)
return child.children.some(nephew =>
return nephew.path === this.$router.history.current.path;
)
else
return child.path === this.$router.history.current.path;
)
else
return menu.path === this.$router.history.current.path;
);
【问题讨论】:
您的意思是要查找给定对象的父对象吗? 是的,创建一个新的清理对象也很好 【参考方案1】:以下递归代码给出了请求的过滤。 请注意,出于测试目的,我将给定的数据“菜单”包含在一个数组中。
cnt 变量 (int) 用于调试目的并指示递归级别。可以省略。
items 变量(对象数组)是包含对象的初始数组。
目标变量(字符串)是所需的路径。
sol 变量(对象数组)是一个最初为空的数组,将填充通向目标的路径。必须在对 itemFilter 的任何新调用之前清除它
let cnt = 0 //For debugging only
const itemFilter= function(items, target, cnt, sol )
cnt += 1
for( let i = 0; i<items.length; i++)
let item = items[i]
if ( item.path == target)
sol.push(item)
//console.log("DEBUG 1 : ", cnt, i, item.path, "Hit")
//console.log(sol)
return sol
//Otherwise...
//console.log(cnt, i, item.path, "No hit")
if (item.children)
itemFilter(item.children, target, cnt, sol)
//console.log("DEBUG 2 : ", cnt, i)
//console.log(sol)
if (sol.length > 0)
sol.push(item)
return sol
console.log("Suggested solution")
console.log("--------------------------------------------------------")
let t = "/actions/step/import"
console.log("CASE 1 : ", t)
let filteredItems = []
itemFilter(menus, t, 0, filteredItems)
console.log(filteredItems)
console.log("--------------------------------------------------------")
t = "/warehouse/new-warehouse-item"
console.log("CASE 2 : ", t)
filteredItems = []
itemFilter(menus, t, 0, filteredItems)
console.log(filteredItems)
console.log("--------------------------------------------------------")
t = "/UNDEFINEDPATH/anything"
console.log("CASE 3 : ", t)
filteredItems = []
itemFilter(menus, t, 0, filteredItems)
console.log(filteredItems)
/*This is the console output (without debugging) :
Suggested solution
--------------------------------------------------------
CASE 1 : /actions/step/import
[ path: '/actions/step/import', title: 'Importazione' ,
path: '/actions/step',
icon: 'fa fa-wine-bottle',
title: 'Fasi',
children:
[ [Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object] ] ]
--------------------------------------------------------
CASE 2 : /warehouse/new-warehouse-item
[ path: '/warehouse/new-warehouse-item',
title: 'Nuovo Oggetto' ,
path: '/warehouse/list-warehouse-item',
title: 'Lista Oggetti',
children: [ [Object] ] ,
path: '/warehouse',
icon: 'fa fa-warehouse',
title: 'Magazzino',
children: [ [Object] ] ]
--------------------------------------------------------
CASE 3 : /UNDEFINEDPATH/anything
[]
*/
【讨论】:
【参考方案2】:基于@Myrer 的出色贡献,为了省略子对象,我将他的脚本编辑如下:
const itemFilter = function(items, target, sol)
for(let i = 0; i < items.length; i++)
let item = items[i];
if (item.path === target)
const itemToPush =
path: item.path,
title: item.title
;
if(item.icon)
itemToPush['icon'] = item.icon;
sol.push(itemToPush);
return sol;
if (item.children)
itemFilter(item.children, target, sol);
if (sol.length > 0)
const itemToPush =
path: item.path,
title: item.title
;
if(item.icon)
itemToPush['icon'] = item.icon;
sol.push(itemToPush);
return sol;
let t = '/warehouse/new-warehouse-item';
let filteredItems = [];
itemFilter(this.menus, t, filteredItems);
console.log(filteredItems.reverse()); // Reversed the order of the array
// Output:
// [
//
// "path": "/warehouse",
// "title": "Magazzino",
// "icon": "fa fa-warehouse"
// ,
//
// "path": "/warehouse/list-warehouse-item",
// "title": "Lista Oggetti"
// ,
//
// "path": "/warehouse/new-warehouse-item",
// "title": "Nuovo Oggetto"
//
// ]
【讨论】:
以上是关于使用 Javascript 根据深度值过滤嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章
在 ES6 深度嵌套的对象的 javascript 数组中查找值