[英]Filter nested object based on deep value with Javascript
我有這個嵌套的 object:
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'
}
]
}
]
}
我想要實現的是根據路徑值過濾嵌套的 object 。
所以如果我有/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;
}
});
以下遞歸代碼給出了請求的過濾。 請注意,出於測試目的,我將給定的數據“菜單”包含在一個數組中。
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
[]
*/
基於@Myrer 的出色貢獻,為了省略孩子 object,我將他的腳本編輯如下:
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"
// }
// ]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.