Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to find all matching values based on search input of objects for the nested array of objects

I am looking for a suggestion and fix in my function.

I have a function to find all possible matches for an array of objects having a nested array of objects.

I have tried adding the filter function but it is only giving me matched keywords for the first level and it is getting stopped after that.

Is there anyways I can search for multiple levels?

I have tried the following.

const data = [
  {
    name: "testmapping",
    items: [
      {
        name: "lv2test1mapping",
        items: [
          { name: "lv3test1mapping" },
          { name: "lv3test2mapping" },
          { name: "lv3test3mapping" }
        ]
      },
      {
        name: "lv2test2mapping"
      },
      {
        name: "lv2test3mapping"
      }
    ]
  },
  {
    name: "test2mapping",
    items: [
      {
        name: "lv2test21mapping",
        items: [
          { name: "lv3test21mapping" },
          { name: "lv3test22mapping" },
          { name: "lv3test23mapping" }
        ]
      },
      {
        name: "lv2test22mapping"
      },
      {
        name: "lv2test23mapping"
      }
    ]
  }
];

function getvalue(searchText) {
  return data.filter(item => {
    return Object.keys(item).some(key => {
      return String(item[key])
        .toLowerCase()
        .includes(searchText.toLowerCase());
    });
  });
}

console.log("one level", getvalue("test"));
//output
[
   {
      "name":"testmapping",
      "items":[
         {
            "name":"lv2test1mapping",
            "items":[
               {
                  "name":"lv3test1mapping"
               },
               {
                  "name":"lv3test2mapping"
               },
               {
                  "name":"lv3test3mapping"
               }
            ]
         },
         {
            "name":"lv2test2mapping"
         },
         {
            "name":"lv2test3mapping"
         }
      ]
   },
   {
      "name":"test2mapping",
      "items":[
         {
            "name":"lv2test21mapping",
            "items":[
               {
                  "name":"lv3test21mapping"
               },
               {
                  "name":"lv3test22mapping"
               },
               {
                  "name":"lv3test23mapping"
               }
            ]
         },
         {
            "name":"lv2test22mapping"
         },
         {
            "name":"lv2test23mapping"
         }
      ]
   }
]
console.log("second level", getvalue("lv2"));
//expected output
[
   {
      "name":"lv2test1mapping",
      "items":[
         {
            "name":"lv3test1mapping"
         },
         {
            "name":"lv3test2mapping"
         },
         {
            "name":"lv3test3mapping"
         }
      ]
   },
   {
      "name":"lv2test2mapping"
   },
   {
      "name":"lv2test3mapping"
   },
   {
      "name":"lv2test21mapping",
      "items":[
         {
            "name":"lv3test21mapping"
         },
         {
            "name":"lv3test22mapping"
         },
         {
            "name":"lv3test23mapping"
         }
      ]
   },
   {
      "name":"lv2test22mapping"
   },
   {
      "name":"lv2test23mapping"
   }
]

console.log("third level", getvalue("lv3"));
//expected output

[
   {
      "name":"lv3test1mapping"
   },
   {
      "name":"lv3test2mapping"
   },
   {
      "name":"lv3test3mapping"
   },
   {
      "name":"lv3test21mapping"
   },
   {
      "name":"lv3test22mapping"
   },
   {
      "name":"lv3test23mapping"
   }
]

https://stackblitz.com/edit/js-ydnhcg?file=index.js

like image 242
a.p. patel Avatar asked Nov 06 '22 02:11

a.p. patel


1 Answers

const data = [
  {
    name: "testmapping",
    items: [
      {
        name: "lv2test1mapping",
        items: [
          { name: "lv3test1mapping" },
          { name: "lv3test2mapping" },
          { name: "lv3test3mapping" }
        ]
      },
      {
        name: "lv2test2mapping"
      },
      {
        name: "lv2test3mapping"
      }
    ]
  },
  {
    name: "test2mapping",
    items: [
      {
        name: "lv2test21mapping",
        items: [
          { name: "lv3test21mapping" },
          { name: "lv3test22mapping" },
          { name: "lv3test23mapping" }
        ]
      },
      {
        name: "lv2test22mapping"
      },
      {
        name: "lv2test23mapping"
      }
    ]
  }
];


function getValue(searchText) {
  const localData = [...data];
  function getValueLogic(data, searchText) {
    const arr = [];
    if (data && Array.isArray(data)) {
      for (let i = 0; i < data.length; i++) {
        const ele = data[i];
        ele && ele.name.includes(searchText)
          ? arr.push(ele)
          : arr.push(...getValueLogic(ele.items, searchText));
      }
    }
    return arr;
  }
  return getValueLogic(localData, searchText);
}



console.log("one level", getValue("test"));
console.log("second level", getValue("lv2"));
console.log("third level", getValue("lv3"));
console.log("Actual Data", data);

Recursion is the key! The below function should meet your requirement.

const data = [...] //your data

function getValue(searchText) {
  const localData = [...data];
  function getValueLogic(data, searchText) {
    const arr = [];
    if (data && Array.isArray(data)) {
      for (let i = 0; i < data.length; i++) {
        const ele = data[i];
        ele && ele.name.includes(searchText)
          ? arr.push(ele)
          : arr.push(...getValueLogic(ele.items, searchText));
      }
    }
    return arr;
  }
  return getValueLogic(localData, searchText);
}



console.log("one level", getValue("test"));
console.log("second level", getValue("lv2"));
console.log("third level", getValue("lv3"));
console.log("Actual Data", data);
like image 106
Prasenjeet Paul Avatar answered Nov 12 '22 14:11

Prasenjeet Paul