What is the best approach for filtering a nested array in this scenario?

Here is the response I am getting:

 let m =  [
      {
        name: 'Summary',
        subListExpanded: false,
        subList: [
        ]
      },
      {
        name: 'Upload',
        subListExpanded: false,
        subList: [
        ]
      },
      {
        name: 'Tasks',
        subListExpanded: false,
        subList: [
        ]
      },
      {
        name: 'Dashboard',
        subListExpanded: false,
        subList: [
        ]
      },
      {
        name: 'Master',
        subListExpanded: false,
        subList: [
          {
            id: 'user-master',
            name: 'User-Master'
          },
          {
            id: 'menu-master',
            name: 'Menu-Master'
          },
          {
            id: 'entity-master',
            name: 'Entity-Master'
          },
          {
            id: 'vendor-master',
            name: 'Vendor-Master'
          },
          {
            id: 'xxx-master',
            name: 'xxx-Master'
          }
        ]
      }
    ];

If I search for m, the filtered result should look like this:

 [
  {
    name: 'Summary',
    subListExpanded: false,
    subList: [
    ]
  },
  {
    name: 'Master',
    subListExpanded: false,
    subList: [
      {
        id: 'user-master',
        name: 'User-Master'
      },
      {
        id: 'menu-master',
        name: 'Menu-Master'
      },
      {
        id: 'entity-master',
        name: 'Entity-Master'
      },
      {
        id: 'vendor-master',
        name: 'Vendor-Master'
      },
      {
        id: 'xxx-master',
        name: 'xxx-Master'
      }
    ]
  }
];

If I search for master, the filter response should be as follows:

[
      {
        name: 'Master',
        subListExpanded: false,
        subList: [
          {
            id: 'user-master',
            name: 'User-Master'
          },
          {
            id: 'menu-master',
            name: 'Menu-Master'
          },
          {
            id: 'entity-master',
            name: 'Entity-Master'
          },
          {
            id: 'vendor-master',
            name: 'Vendor-Master'
          },
          {
            id: 'xxx-master',
            name: 'xxx-Master'
          }
        ]
      }
    ];

If I search for xxx-master, the filter response will be:

[
{
        name: 'Master',
        subListExpanded: false,
        subList: [
          {
            id: 'xxx-master',
            name: 'xxx-Master'
          }
        ]
      }
    ];

If I search for slkvcsmcskc, the filter response will be:

 []

My TypeScript code is not functioning correctly. Can you assist me in resolving this issue?

  m.filter(x=> x.name.toLowerCase() === search.toLowerCase() || x.subList.some(x1=> x1.name.toLowerCase()===search.toLowerCase()))

Answer №1

The code snippet below demonstrates the functionality you are looking for. It includes additional complexity that might not be necessary for your specific scenario. Nevertheless, this example is designed to handle lists with multiple levels of nesting (as shown in the 'bar' example).

let data =  [
      {
        name: 'Summary',
        subListExpanded: false,
        subList: [
        ]
      },
      {
        name: 'Upload',
        subListExpanded: false,
        subList: [
          {
            name: 'foo',
            subList: [
              {
                name: 'bar',
              }
            ],
          }
        ]
      },
      {
        name: 'Tasks',
        subListExpanded: false,
        subList: [
        ]
      },
      {
        name: 'Dashboard',
        subListExpanded: false,
        subList: [
        ]
      },
      {
        name: 'Master',
        subListExpanded: false,
        subList: [
          {
            id: 'user-master',
            name: 'User-Master'
          },
          {
            id: 'menu-master',
            name: 'Menu-Master'
          },
          {
            id: 'entity-master',
            name: 'Entity-Master'
          },
          {
            id: 'vendor-master',
            name: 'Vendor-Master'
          },
          {
            id: 'xxx-master',
            name: 'xxx-Master'
          }
        ]
      }
    ];
    
    
function customSearch (input, query) {
  const queryRegEx = new RegExp(query, 'i');
  
  function internalSearch (data) {
    let resultArr = [];

    data.forEach(item => {
      const parentMatch = queryRegEx.test(item.name);
      let subMatchFound = false;
   
      if (item.subList) {
        let subResultArray = internalSearch(item.subList);
        subMatchFound = subResultArray.length > 0;

        item.subList = subMatchFound ? subResultArray : [];
      }
      
      // Add parent item to result array if it matches the query or any child items match
      if (parentMatch || subMatchFound) resultArr.push(item);
    });
    
    return resultArr;
  }
  
  return internalSearch(JSON.parse(JSON.stringify(input)) /* create a clone using JSON.parse(...) */);
}

console.log('master', customSearch(data, 'master'));
console.log('xxx-master', customSearch(data, 'xxx-master'));
console.log('m', customSearch(data, 'm'));
console.log('bar', customSearch(data, 'bar'));
console.log('slkvcsmcskc', customSearch(data, 'slkvcsmcskc'));

Answer №2

It is important to note that the correct structure should be as follows:

obj = {
    _id: "sjkd9skj",
    data: {
      dektop: [
                { 
                   x: 2,
                   y: 3,
                   t: { key: 'aabbcc'}
                }, 
                ... 
              ],
      mobile: [
                { 
                   x: 4,
                   y: 3,
                   t: { key: 'ffff'}
                }, 
                ... 
              ],
      print: [
                { 
                   x: 7,
                   y: 5,
                   t: { key: 'ppp'}
                }, 
                ... 
              ]
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process for implementing a decorator pattern using typescript?

I'm on a quest to dynamically create instances of various classes without the need to explicitly define each one. My ultimate goal is to implement the decorator pattern, but I've hit a roadblock in TypeScript due to compilation limitations. Desp ...

Has the web application continued to run in the background even after toggling between tabs on the browser?

Does the app continue running in the background even when I'm not on that specific tab? Or does it pause when I switch between tabs, requiring a new request to the server for any updated data from the database upon returning to that tab? Edit: Curren ...

When trying to click on an HTMLTableRowElement, an Uncaught ReferenceError occurs in React.js and jQuery, stating that the function is

When I was working on my web app, I encountered an issue while trying to create a table. Upon clicking on it, I received an error message: Uncaught ReferenceError: (function) is not defined at HTMLTableRowElement.onclick Here is the code for the table: $( ...

Developing mongoose models using TypeScript for subdocuments

Exploring the integration of mongoose models with typescript, following a guide available at: https://github.com/Appsilon/styleguide/wiki/mongoose-typescript-models. Unsure how arrays of subdocuments align with this setup. For instance, consider the model ...

Instructions on creating a countdown timer that reveals a hidden div once it reaches zero, remains visible for a set period, and then resets

I created a countdown timer that displays a div when the timer reaches zero. However, I am struggling with getting the timer to reset and start counting down again after displaying the div. For instance, if I set the timer for 7 days and it reaches the de ...

Problem with targeting the .prev() and closest() class of a text input box

Could you please review This Demo and advise why I am unable to select the first .fa class before the text box #name ? This is what I have been trying: $(this).prev().closest(".fa").addClass("err"); within this code block <div class="row"> & ...

What is the method for activating a button when a user inputs the correct email address or a 10-digit mobile number

How can I enable a button when the user enters a correct email or a 10-digit mobile number? Here is my code: https://stackblitz.com/edit/angular-p5knn6?file=src%2Findex.html <div class="login_div"> <form action=""> <input type="text" ...

Creating objects based on user input in AngularJS is a common task for developers. This tutorial will

When populating a form with radio buttons based on a JSON object, the user can select options and upon clicking submit, all radio button data is saved into an object. <form name="regForm"> <ul> <li ng-repeat="q in ...

While attempting to read and write to a JSON file, I encountered the error: "raise JSONDecodeError("Expecting value", s, err.value) from None"

Hey there! I've been working on a project where I need to read from a json file with a dictionary structure and update it by adding more entries. However, I'm encountering an error that I can't seem to figure out. I've spent 10 hours tr ...

New update in Fullcalendar v2: Enhancements to dayRender function for agenda view and agenda

For the newest version of FullCalendar, I am in need of the dayRender callback to modify the color of disabled days. Unfortunately, this specific callback only functions for month, basicWeek, and basicDay views. However, I require this functionality for a ...

Unraveling the mysteries of an undefined entity

When the variable response is undefined, attempting to retrieve its property status will result in an error: Error: Unable to access property 'status' of undefined const { response, response: { status }, request, config, } = error as A ...

Tips for adjusting the default selection in a second dropdown menu

I have a dilemma with my two dropdown lists, "optionone" and "optiontwo". I am trying to alter the default selected value from "option value=3>3" to option value=3 selected>3 when the user selects 2 from the first dropdown list ("optionone"). <script&g ...

Transform a numerical variable into a string data type

I am faced with a situation where I have a variable named val which is currently set to the number 5. Now, my goal is to update the value of val so that it becomes a string containing the character "5". Could someone guide me on how to achieve this? ...

Providing the correct context to the function in Angular's dialog data is crucial for seamless

Currently, I have a scenario where a service and a component are involved. In the service, there is an attempt to open a dialog in which a reference to a method existing in the service is passed. The code snippet below provides an example: export class So ...

By executing array1.splice(1,1), I am deleting elements from array2 that was generated by copying array1 with array1.slice(0)

I was working with JSON data and converted it into an array of objects. Then, I assigned that array to another array using the .slice(0) method. However, I encountered an issue where when I tried to remove an element from the assigned array, it also remov ...

GSON encountering the error message "Anticipated BEGIN_OBJECT, but received STRING instead

Here is a Json Object example: [ { "UserId":"demouser1", "Catagories":[ { "CatagoryName":"Entertainment", "Persent":"25" }, { "CatagoryName":"Household", "Persent":"25" }, { " ...

Python OSError: [Errno 9] Issue with file descriptor encountered upon attempting to open large JSON file

Recently, I attempted to process a large json file (the Wikipedia json dump) in Python by reading it line by line. However, I encountered the following Error: Traceback (most recent call last): File "C:/.../test_json_wiki_file.py", line 19, in ...

Utilizing Django fixtures: Importing HTML content as JSON into a Text Field

Currently in the process of transitioning my website to Django from another content management system, I am facing challenges with importing HTML into Django using fixtures. The specific issue revolves around "Events", which is a model within my Django app ...

Is it feasible to indent lines in a template without affecting the content alignment?

Creating a string with newlines that will be included in an email later. if (action) { description = ` Git pull request action: ${action} Git pull request for repo: ${req.body.repository.full_name} Git pull request for repo URL: ${re ...

Upon calling the createModalAddPost() function, a single window is triggered to open

Hey there, I'm having a JavaScript question. So, I have a panel that opens a window, and it works fine. But the issue arises when I close the window and try to open it again - it doesn't work. I have to reload the page every time in order to open ...