Filtering nested arrays in Javascript involves iterating through each nested

I have a nested array inside an array of objects in my Angular app that I'm attempting to filter. Here is a snippet of the component code:

var teams = [
  { name: 'Team1', members: [{ name: 'm1' }, { name: 'm2' }, { name: 'm3' }] }, 
  { name: 'Team2', members: [{ name: 'm4' }, { name: 'm5' }, { name: 'm6' }] }, 
  { name: 'Team3', members: [{ name: 'm7' }, { name: 'm8' }, { name: 'm9' }] }
];

My goal is to filter based on a search query, for example if I search for m5, I want my result to look like this:

var teams = [
  { name: 'Team1', members: [] }, 
  { name: 'Team2', members: [{ name: 'm5' }] }, 
  { name: 'Team3', members: [] }
];

To achieve this, I have properties teams and filteredTeams, and in my search function I am doing the following:

onSearchChange(event: any): void {
  let value = event.target.value;
  this.filteredTeams = this.teams.map(t => {
    t.members = t.members.filter(d => d.name.toLowerCase().includes(value));
    return t;
  })
}

While this approach works partially, it replaces the members array on each call which is not ideal. I understand the issue here, but I'm unsure about the best way to implement this filter. Any suggestions?

Answer №1

your approach was almost correct, but the mistake you made was altering the original objects in the teams array.

To fix this issue, you can utilize the spread operator to create a new entry and then generate an entirely new array with updated values.

const teams = [
  { name: 'Team1', members: [{ name: 'm1' }, { name: 'm2' }, { name: 'm3' }] }, 
  { name: 'Team2', members: [{ name: 'm4' }, { name: 'm5' }, { name: 'm6' }] }, 
  { name: 'Team3', members: [{ name: 'm7' }, { name: 'm8' }, { name: 'm9' }] }
];

const value = 'm5';

const result = teams.map(t => {
  const members = t.members.filter(d => d.name.toLowerCase().includes(value));
  return { ...t, members };
})

console.log(result)

Answer №2

Give this a try. Instead of using a set value like m5, input your own.

const teams = [
  { name: 'Team1', members: [{ name: 'm1' }, { name: 'm2' }, { name: 'm3' }] }, 
  { name: 'Team2', members: [{ name: 'm4' }, { name: 'm5' }, { name: 'm6' }] }, 
  { name: 'Team3', members: [{ name: 'm7' }, { name: 'm8' }, { name: 'm9' }] }
];

const filteredTeams = teams.map(team => ({ name: team.name, members: team.members.filter(member => member.name.includes('m5')) }));

console.log(filteredTeams);

Answer №3

Instead of mutating the original objects, consider assigning new properties to the result object for mapping purposes.

var teams = [{ name: 'Team1', members: [{ name: 'm1' }, { name: 'm2' }, { name: 'm3' }] }, { name: 'Team2', members: [{ name: 'm4' }, { name: 'm5' }, { name: 'm6' }] }, { name: 'Team3', members: [{ name: 'm7' }, { name: 'm8' }, { name: 'm9' }] }],
    result = teams.map(o => Object.assign(
        {},
        o,
        { members: o.members.filter(({ name }) => name === 'm5') }
    ));
    
console.log(result);
console.log(teams);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №4

To enhance your search functionality, it's a good idea to refactor your filter function like this:

const customFilterFunction = (data, filters) => {
    const filteredValues = filters.map(filter => filter.toLowerCase());
    
    return data.map(item => ({
        ...item,
        values: item.values.filter(value => filteredValues.includes(value.name))
    }))
};
// -----

updateSearch(event: any): void {
    let inputValue = event.target.value;
    this.filteredData = customFilterFunction(this.data, [inputValue]);
}

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

The array is present both before and after the res.json() call, however it appears empty in the response

When using Express to send a json response with res.json(), I am experiencing an issue where the value of records in the object sent via res.json() is empty. My code snippet looks like this: stats.activities(params).then(res => { processActivities ...

It appears that Typescript mistakenly interprets a class or type as a value, indicating that "'Classname' is being referred to as a value but used as a type here."

I want to pass an Object of a React.Component as "this" to a Child React.Component in the following way: component 1 file: class Comp1 extends React.Component<...,...> { ... render() { return (<Comp2 comp1={this}/> ...

What could be causing Highchart to return the error message "Typeerror: undefined variable byte"?

My current project involves creating a graph using highchart and updating values every second. I am also working on displaying data in Mb, Kb, and Gb format on the graph by developing a function to convert byte values. Here is a snippet of my code: // hi ...

Updating webdriver-manager can sometimes result in a "spawn Unknown system error -86" message. This error

(Angular). webdriver-manager 12.1.7 is causing issues specifically on Intel-based Macs. When running e2e tests, the error message "spawn Unknown system error -86" is encountered. The bug has been addressed in webdriver-manager 12.1.8, however, I am facing ...

Looking to compare two elements within different arrays? The method outlined below is specifically designed for comparing to individual values rather than entire arrays

Is this the right approach? How can we iterate through each array to compare values? Should these data structures be modified or transformed first? Below is the data that needs to be compared. The objective is to match userID with DocumentID. const videos ...

Check input validations in Vue.js when a field loses focus

So I've created a table with multiple tr elements generated using a v-for loop The code snippet looks like this: <tr v-for="(item, index) in documentItems" :key="item.id" class="border-b border-l border-r border-black text ...

Barba.js (Pjax.js) and the power of replacing the <head> tag

I have been using barba.js to smoothly transition between pages without having to reload the entire site. If you want to see an example, take a look here. Here is a snippet of code from the example: document.addEventListener("DOMContentLoaded", func ...

Changing the background color of required inputs that are empty using jQuery

I need help customizing the background color of required input fields that are left empty when a user submits a form. Some of the fields are optional, but I want only the required ones to be highlighted in red. Specifically, the required fields have been ...

Respond to unsuccessful changes within a simple presentational element

Within my component, I have a feature that allows users to interact with and modify a specific entity. However, these modifications may be rejected at the server level. In such cases, I would like the component to initiate an animation to indicate to the u ...

Angular.js reports that the custom HTTP response header is missing

Despite Chrome showing the correct POST response headers, my custom HTTP header X-Auth-Token is returning null in the callback function for the POST request. Angular.js seems to only be returning Cache-Control and Content-Type, with everything else showing ...

What is the procedure for utilizing Javascript to redirect a user on a website back to the login page if necessary?

Is there a way to redirect a website user back to the login page if they try to access a secure page without logging in first? I'm looking to implement this using JavaScript and cookies. Any suggestions or ideas on how to achieve this seamlessly for t ...

Encountering a problem while attempting to start Gulp

I encountered an error while updating modules and I'm not sure how to resolve it. Every time I attempt to update, the same error reappears. I tried updating the core JS using the following commands: npm outdated npm install npm install I also referr ...

Using Vue to turn a string into a mathematical operation

I'm in the process of creating a basic calculator using Vue, but I'm stuck on how to convert a string into a mathematical operation. I've already written the code for building the strings. <template> <div> <input type=&q ...

Troubleshooting React: Child Component Fails to Render

Currently, I am enrolled in a React course and deep diving into the lifecycle methods of React. Through implementing componentDidMount, I have successfully made API calls and set the state accordingly. However, I am facing an issue with displaying images ...

Connecting radio buttons to data in Vue using render/createElement

How do you connect the value of a selected radio button to a specific variable in the data object within a Vue application when using the render/createElement function? ...

Vue.js is displaying one less item

Recently I started working with Vuejs and encountered an unexpected issue in my application. The purpose of my app is to search for channels using the YouTube API and then display those channels in a list. However, when I try to render the list of subscri ...

Elevation in design ui component

I am having an issue with the height of a theme-ui component I embedded. Even though the console shows it correctly, it is displaying at 100% height. <Embed src={url} sx={{width: '800px', height: '400px'}}/> This embed is contain ...

What could be causing this minimal Angular - WebTorrent configuration to fail?

The setup appears to be quite straightforward. Check out the Webtorrent usage reference here This is how I have my setup: import WebTorrent from 'webtorrent'; @Component({ selector: 'app-root', standalone: true, template: `bla` ...

How can we avoid having the same event duplicated on a canvas, leading to the unnecessary rendering of multiple layers of the same event?

I have encountered an issue with my Chrome extension on certain websites where, upon scrolling, the same element is rendered multiple times, causing a significant decrease in performance. This rendering occurs as soon as I stop scrolling, leading to layers ...

Sending a JavaScript variable to PHP in order to specify the timezone

I'm working on setting the timezone for every user in the navbar.php file that's included on all pages of my website. After finding a helpful js script, I am able to echo the variable 'Europe/Brussels' to identify my timezone correctly. ...