Home > Software design >  Recursively filter array of objects problem in return
Recursively filter array of objects problem in return

Time:12-20

I have a fixed array like this And a return function to find the desired value. My problem is that even when the submenu is empty, an empty variable returns to the submenu: [] which I do not want

const myMenu = {items : [{
  title: "menu 1",
  root: true,
  icon: "flaticon2-architecture-and-city",
  page: "dashboard",
  bullet: "dot",
  MenuId:1,
},
{
  title: "menu 2",
  root: true,
  bullet: "dot",
  icon: "flaticon2-browser-2",
  MenuId:2,
  submenu: [
    {
      title: "sub menu 1",
      bullet: "dot",
      page: "AssetMainPage",
      MenuId:3,

    },
    {
      title: "sub menu 2",
      page: "Departments",
      bullet: "dot",
      MenuId:4,  
    },
  ],
},
{
  title: "menu 3",
  root: true,
  icon: "flaticon2-architecture-and-city",
  page: "dashboard",
  bullet: "dot",
  MenuId:5,
  submenu: [
    {
      title: "sub menu 1",
      page: "AssetMeter",
      MenuId:6,
    },
    {
      title: "sub menu 2",
      page: "ChangeAssetStatus",
      MenuId:7,
    },
    {
      title: "گزارش وضعیت و کارکرد",
      page: "AssetsMeterAndStatusReports",
      MenuId:8,
    },
  ],

},
]}

And I have this Recursively function for find and retrn array :

function filter(arr, term) {
  var matches = [];
  if (!Array.isArray(arr)) return matches;
  arr.forEach(function(i) {
      if (i.MenuId === term) {
       const filterData =  (i.submenu && Array.isArray(i.submenu))? i.submenu.filter(values => values.MenuId === term):[];
      // console.log(filterData)
       i.submenu =filterData;
          matches.push(i);
      } else {
      //console.log(i.children)
      let childResults = filter(i.submenu, term);
      if (childResults.length ) {  
          matches.push(Object.assign({}, i,{submenu: childResults} ));
      }  
    }
  })
  return matches;
}

My question is whether I can not return that variable at all when the submenu array is empty. Like the following output:

 // call function 
  const filterData = filter(myMenu.items,7); 
  console.log("filterData",filterData)

i want this result :

  title: "menu 3",
  root: true,
  icon: "flaticon2-architecture-and-city",
  page: "dashboard",
  bullet: "dot",
  MenuId:5,
  submenu :[
      title: "sub menu 2",
      page: "ChangeAssetStatus",
      MenuId:7,
      // exactly here i dont want return empty submenu:[] 
] 
  

CodePudding user response:

Inside your arr.forEach function:

function filter(arr, term) {
  var matches = [];
  if (!Array.isArray(arr)) return matches;
  arr.forEach(function (i) {
    if (i.MenuId === term) {
      const filterData =
        i.submenu && Array.isArray(i.submenu)
          ? i.submenu.filter((values) => values.MenuId === term)
          : [];
      // console.log(filterData)
      i.submenu = filterData;
      if (!i.submenu.length) {
        delete i.submenu;
      }
      matches.push(i);
    } else {
      //console.log(i.children)
      let childResults = filter(i.submenu, term);
      if (childResults.length) {
        matches.push(Object.assign({}, i, { submenu: childResults }));
      }
    }
  });
  return matches;
}

CodePudding user response:

Just before assign value to submenu property you can check that filtedData is an empty array or not, by checking it's length property:

...
const filterData = (i.submenu && Array.isArray(i.submenu))? i.submenu.filter(values => values.MenuId === term):[];
if(filterData.length){ i.submenu =filterData; }
...
  • Related