0

I have this nested 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'
          }
        ]
      }
    ]
  }

What I'm trying to achieve is to filter the nested object based on the path value.

So if I have /actions/step/import I would like to have this:

[{ 
    path: '/actions/step',
    icon: 'fa fa-wine-bottle',
    title: 'Fasi'
},
{
    path: '/actions/step/import',
    title: 'Importazione'
}]

Or in case /warehouse/new-warehouse-item I would have:

[{ 
    path: '/warehouse', 
    icon: 'fa fa-warehouse', 
    title: 'Magazzino'
},
{
    path: '/warehouse/list-warehouse-item',
    title: 'Lista Oggetti'
},
{
    path: '/warehouse/new-warehouse-item',
    title: 'Nuovo Oggetto'
}]

What I've tried to do is filtering like this way but it's incomplete (this.$router.history.current.path contains the string 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;
    }
});
2
  • Do you mean you want to find the parent(s) of given object(s)? Commented Dec 18, 2021 at 1:28
  • Yes, also creating a new cleaned object would be good Commented Dec 18, 2021 at 1:30

2 Answers 2

1

The following recursive code gives the requested filtering. Please note that I included the given data "menus" in an Array for test purposes.

The cnt variable (int) is used for debugging purposes and indicates the level of recursion. It can be omitted.

The items variable (array of objects) is the initial array that contains the objects.

The target variable (string) is the desired path.

The sol variable (array of objects) is an initially empty array that will be populated with the paths that lead to the target.It must be cleared before any new call to 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
[]

*/

Sign up to request clarification or add additional context in comments.

Comments

0

Based on the excellent contribute of @Myrer, to omit the children object I edited his script like this:

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"
//     }
// ]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.