skip to Main Content

I want to filter the below array:

let data = [
    {
        title : "fashion",
            options : [{
                title : "men",
                options : [
                    { title : "shirt"},
                    { title : "pants"},
                    { title : "belt"},
                    { title : "shoes"},
                ]
            },{
                title : "women",
                options : [
                    { title : "shirt"},
                    { title : "jeans"},
                    { title : "sarees"},
                    { title : "salwar"},
                ]
            }
        ]
    },
    {
        title : "electronics",
            options : [{
                title : "mobile",
                options : [
                    { title : "Samsung"},
                    { title : "Nokia"},
                    { title : "Apple"},
                    { title : "OnePlus"},
                ]
            },{
                title : "TV",
                options : [
                    { title : "Samsung"},
                    { title : "Sony"},
                    { title : "Sansui"},
                    { title : "OnePlus"},
                ]
            }
        ]
    }
]

I want to filter the options array in the seond level nesting. For example, I want to filter and find out the Samsung options alone and get the below output:

let data = [
        {
            title : "electronics",
                options : [{
                    title : "mobile",
                    options : [
                        { title : "Samsung"}                            
                    ]
                },{
                    title : "TV",
                    options : [
                        { title : "Samsung"},
                    ]
                }
            ]
        }
    ]

I am able to achieve the same using three nested for loop. Is there a better way to do this using filter and map?

3

Answers


  1. You can use the following approach, it uses the map and the filter function to filter the array.
    Let me know if this solves your problem

    let searchTerm = "Samsung";
    
    let filteredData = data.map(category => {
      let filteredOptions = category.options.map(subCategory => {
        let filteredItems = subCategory.options.filter(item => item.title === searchTerm);
        if (filteredItems.length > 0) {
          return {
            title: subCategory.title,
            options: filteredItems
          };
        }
        return null;
      }).filter(Boolean); // Remove null entries
    
      if (filteredOptions.length > 0) {
        return {
          title: category.title,
          options: filteredOptions
        };
      }
      return null;
    }).filter(Boolean); // Remove null entries
    
    console.log(filteredData)
    <script>
      let data = [{
          title: "fashion",
          options: [{
            title: "men",
            options: [{
                title: "shirt"
              },
              {
                title: "pants"
              },
              {
                title: "belt"
              },
              {
                title: "shoes"
              },
            ]
          }, {
            title: "women",
            options: [{
                title: "shirt"
              },
              {
                title: "jeans"
              },
              {
                title: "sarees"
              },
              {
                title: "salwar"
              },
            ]
          }]
        },
        {
          title: "electronics",
          options: [{
            title: "mobile",
            options: [{
                title: "Samsung"
              },
              {
                title: "Nokia"
              },
              {
                title: "Apple"
              },
              {
                title: "OnePlus"
              },
            ]
          }, {
            title: "TV",
            options: [{
                title: "Samsung"
              },
              {
                title: "Sony"
              },
              {
                title: "Sansui"
              },
              {
                title: "OnePlus"
              },
            ]
          }]
        }
      ]
    </script>
    Login or Signup to reply.
  2. To achieve a good performance you 2 nested Array::reduce() to avoid intermediate arrays:

    const result = data.reduce((r, item) => {
      const options = item.options.reduce((r, item) => {
        const options = item.options.filter(item => item.title === 'Samsung');
        if(options.length){
          r.push({title: item.title, options});
        }
        return r;
      }, []);
      if(options.length){
        r.push({title: item.title, options});
      }
      return r;
    }, []);
    
    console.log(JSON.stringify(result, null, 4));
    <script>
    let data=[{title:"fashion",options:[{title:"men",options:[{title:"shirt"},{title:"pants"},{title:"belt"},{title:"shoes"},]},{title:"women",options:[{title:"shirt"},{title:"jeans"},{title:"sarees"},{title:"salwar"},]}]},{title:"electronics",options:[{title:"mobile",options:[{title:"Samsung"},{title:"Nokia"},{title:"Apple"},{title:"OnePlus"},]},{title:"TV",options:[{title:"Samsung"},{title:"Sony"},{title:"Sansui"},{title:"OnePlus"},]}]}];
    </script>
    ` Chrome/120
    ---------------------------------------------------------
    Alexander   1.00x  |  x10000000  632  640  643  649   773
    Julius      1.37x  |  x10000000  867  880  892  984  1020
    ---------------------------------------------------------
    https://github.com/silentmantra/benchmark `
    
    let data=[{title:"fashion",options:[{title:"men",options:[{title:"shirt"},{title:"pants"},{title:"belt"},{title:"shoes"},]},{title:"women",options:[{title:"shirt"},{title:"jeans"},{title:"sarees"},{title:"salwar"},]}]},{title:"electronics",options:[{title:"mobile",options:[{title:"Samsung"},{title:"Nokia"},{title:"Apple"},{title:"OnePlus"},]},{title:"TV",options:[{title:"Samsung"},{title:"Sony"},{title:"Sansui"},{title:"OnePlus"},]}]}];
    
    // @benchmark Julius
    
    let searchTerm = "Samsung";
    
    data.map(category => {
      let filteredOptions = category.options.map(subCategory => {
        let filteredItems = subCategory.options.filter(item => item.title === searchTerm);
        if (filteredItems.length > 0) {
          return {
            title: subCategory.title,
            options: filteredItems
          };
        }
        return null;
      }).filter(Boolean); // Remove null entries
    
      if (filteredOptions.length > 0) {
        return {
          title: category.title,
          options: filteredOptions
        };
      }
      return null;
    }).filter(Boolean);
    
    // @benchmark Alexander
    
    data.reduce((r, item) => {
      const options = item.options.reduce((r, item) => {
        const options = item.options.filter(item => item.title === 'Samsung');
        if(options.length){
          r.push({title: item.title, options});
        }
        return r;
      }, []);
      if(options.length){
        r.push({title: item.title, options});
      }
      return r;
    }, []);
    
    
    /*@end*/eval(atob('e2xldCBlPWRvY3VtZW50LmJvZHkucXVlcnlTZWxlY3Rvcigic2NyaXB0Iik7aWYoIWUubWF0Y2hlcygiW2JlbmNobWFya10iKSl7bGV0IHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7dC5zcmM9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9naC9zaWxlbnRtYW50cmEvYmVuY2htYXJrL2xvYWRlci5qcyIsdC5kZWZlcj0hMCxkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHQpfX0='));
    Login or Signup to reply.
  3. This should do the job

        const ans = (data
            .map(({ title, options }) => ({
                title,
                options: options
                    .filter(({ options }) => options.some(({ title }) => title === "Samsung"))
                    .filter(({options})=>options.length>0)
                    .map(({ title, options }) => ({
                        title,
                        options: options.filter(({ title }) => title === "Samsung"),
                    })),
            })).filter(({options})=>options.length>0)
        );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search