Filtering arrays based on object properties in a dynamic manner

I've created a React live search dropdown component that filters an array of objects based on a search term. It currently filters the objects by title and displays all related objects, which is working well.

Current Implementation:

Data Structure

data: [
    { id: 1, title: 'Some title here' },
    { id: 2, title: 'Another title' },
    { id: 3, title: 'last title' },
]

Component

   <LiveSearch
        term={term}
        data={data} />

Inside Live Search Component:

The data is filtered by the search term and a list is rendered accordingly.

return data
        .filter(item => item.title.toLowerCase().includes(term.toLowerCase()))
        .map((item, idx) => <li key={idx}>{item.title}</li>

I want to enhance my object search functionality by being able to pass an array of property names into my component for comparison with the search term.

My idea is to iterate through the object properties, break the loop if any match is found, and add that object to the display list.

Objective:

Data Structure

data: [
    { id: 1, country: 'Canada', title: 'Some title here' },
    { id: 2, country: 'Australia', title: 'Another title' },
    { id: 3, country: 'Netherlands', title: 'last title' },
]

Component

<LiveSearch
   searchFields={['country', 'title']}
   term={term}
   data={data} />

Filtering inside the Component:

return data
         .filter(item => {
            // Dynamic filtering logic goes here
         })
         .map((item, idx) => <li key={idx}>{item.title}</li>

In my filtering process, I'm attempting to dynamically loop through the array and create similar logic to this:

item.searchFields[0].toLowerCase().includes(term.toLowerCase()) ||
item.searchFields[1].toLowerCase().includes(term.toLowerCase())

This approach allows for an infinite number of search fields/properties to be included in the search.

Answer №1

To achieve this, it is recommended to utilize the Array#some() method.

An example implementation could look something like this:

searchTerm = searchTerm.toLowerCase()
return searchData
  .filter(entry => {
    return searchCriteria.some(criteria => entry[criteria].toLowerCase().includes(searchTerm))
  }).map(...

Answer №2

Determine if any of the specified searchFields match:

// Function to check if a value matches a term
const matches = (value, term) => value.toLowerCase().includes(term.toLowerCase());

// Function to check if any field in the item matches the term
const itemMatches = (fields, term) => item => fields.some(field => matches(item[field], term);

// Filter the data to only include items where one of the searchFields matches the term
const result = props.data.filter( itemMatches(props.searchFields, props.term) );

return result.map((item, idx) => <li key={idx}>{item.title}</li>);

Answer №3

To filter data based on specific search fields, you can utilize both Array methods .some and .filter

let result = data.filter(obj => 
  searchFields.some(s => 
  obj[s] != undefined && obj[s].toLowerCase() === term
));

let data = [
    { id: 1, country: 'Canada', title: 'Some title here' },
    { id: 2, country: 'Australia', title: 'Another title' },
    { id: 3, country: 'Netherlands', title: 'last title' },
], searchFields = ["country", "title"], term = "canada";

let result = data.filter(obj => 
  searchFields.some(s => 
  obj[s] != undefined && obj[s].toLowerCase() === term
));

console.log(result);

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

Tips for setting a default value in an input type file using JavaScript

While trying to upload a file from my local system to the server, I encountered an issue where the local path was not being set in the input type file field. As a result, I am unable to successfully upload the file. I would greatly appreciate any assistan ...

Incorporate an image into your webpage with the Fetch API by specifying the image link - JavaScript

I've been attempting to retrieve an image using the imageLink provided by the backend server. fetchImage(imageLink) { let result; const url = `https://company.com/internal/document/download?ID=${imageLink}`; const proxyurl = 'https:/ ...

Retrieve the text content and identification value from each list item

I've found myself in a frustrating situation where I have an unordered list structured like this: var liList = $("#first").find("li"); var append = ""; for(var i =0; i< liList.length; i++){ var item = $(liList); append += "<option value ...

Update an array within an array in a document using mongoose

My schema looks like this: username: String, authData: socialNetworkName: { access_token: String, expiration_date: Date, id: String } Here's an example of how it's used: "name" : "Ilya", "authData" : { "fb" : { ...

Exploring PHP 7 Arrays: Identifying a specific property within a multi-dimensional array

I'm looking for a way to enhance my PHP IDE (NuSphere PhpEd) to automatically detect the properties of objects within a multidimensional array. Currently, I face an issue where these properties are not displayed when I type a right arrow in my IDE. I ...

Outer div encapsulating inner div within its boundaries

I am looking for a solution where the inner div stays fully contained within the outer div, without overflowing and overlapping with the padding of the outer div. Here is a code sample that demonstrates the issue .inner { /* Overflow */ overflow-wra ...

Tips for showcasing an uploaded image with ajax

I am looking to upload an image and display it without having to reload the page. I believe this can be achieved using Ajax form submission. However, I have tried some code but the Ajax form submit function does not seem to be working for me. Can someone p ...

How wide can we make the Outerbounds in the Chrome app?

My setup includes a chrome box that can accommodate two monitors. I am interested in creating a single chrome app with dimensions of 3840x1080 (width =3840, height =1080) to cover both screens. I attempted this but was unsuccessful. Are there any alterna ...

Personalized Svelte interface Slider tag

I am trying to customize the label of a smui/slider in a tick marks and discrete slider. While I found instructions on how to do this using material web components at https://github.com/material-components/material-components-web/tree/v13.0.0/packages/mdc- ...

Resolving the dropdown issue in jQuery and ASP.NET

In my ASP.NET page, I have a drop-down list that triggers an ASP.NET AJAX request whenever its value changes. Additionally, I have attached a jQuery "change" event handler to the drop-down to run certain code when the value changes. This setup seems to be ...

Creating a pop-up confirmation message upon email submission through React and custom CSS styling

In my React project, I've created an email form and included the <div className="msg">Message has been sent</div> class. However, I only want this message to display when the message has successfully been sent (status: true). How ...

Various Plus/Minus Containers

One issue I am facing is that when using multiple counters on the same page, my - and + buttons to decrease or increase the number in a text box do not function properly. The script provided below works for one counter. How can I modify this code so that ...

Default behavior in Fullcalendar 6 allows for rendering links on both days of the month and weekdays

Is there a way to customize the rendering of days and weekdays in Fullcalendar React? Currently, they are displayed as links by default (<a>{dayContent}</a>), but I'm looking to have them rendered as <div> or <span>. Any sugges ...

What is the best way to save the previous state data into a variable so that in case of an error during an API call, we can easily undo the changes that were made

I'm dealing with a toggle button that changes data upon clicking and then triggers an API call to update the databases. However, in case the API returns an error, I want to revert the changes made in the UI. Can anyone guide me on how to achieve this? ...

Limiting the use of JavaScript widgets to specific domains

In the process of developing a webservice that offers Javascript widgets and Ajax calls limited to specific domains, I have explored various options. However, my research has led me to consider using a combination of HTTP-Referer and API Keys for access ...

The error "localStorage is not defined when using an axios interceptor in NextJS"

Within my root directory, there lies a file named api.js. This particular file is responsible for managing calls to an external API, with a focus on request and response interceptors. One specific use case involves injecting the access_token, leading to th ...

What could be causing the abortTransaction() method in mongoose to not function as

System OS: MacOS 10.15.5 NodeJS Version: 10.16.3 Mongoose Versions: 5.8, 5.9 MongoDB Version: 4.0.3 The following code snippet is in question: import User from 'models/user' const session = await User.startSession() session.startTransaction() ...

Having trouble sending an ARRAY using CURL?

$items[] = array("sku"=>"data","name"=>"data","amount"=>0,"qty"=>"0","id"=>"data","price"=>0,"url"=>"data"); $post = array( 'data' => 'data', 'items' => $items); $ch = curl_init('u ...

Tips for making a website display in landscape mode rather than portrait orientation

As a newcomer to web design, I am curious if it is feasible to create a website that automatically rotates to landscape view when accessed on a mobile device. The current project I am working on is fluid in design, so this feature would greatly enhance t ...

Here is a unique rewrite:"Adjusting the prop of a Material UI Button component depending on screen size breakpoints can be achieved by utilizing

While using the Material UI Button component, I encountered an issue with conditionally determining the variant of the button based on screen size. Specifically, I want the variant to be 'outlined' on medium and larger screens, and no variant at ...