Is there a way to apply multiple nested criteria to filter an object effectively?

I'm dealing with a specific object and my goal is to filter and retrieve players from both groups based on certain criteria like "show me all players where franchise = Marvel, and power= flight" but I am struggling with the filtering process at multiple levels.

While researching, I came across this answer which didn't quite match my scenario: JavaScript - Filter object based on multiple values

Although I can achieve results by iterating over the groups, there might be numerous groups and I would prefer not to get stuck in that. Is there a better approach to handling this?

oPlayers.players.groups.filter(function(hero){return hero.Id == 1}) 
oPlayers = {
    "players": {
        "groups": [
            {
                "Id": 1,
                "hero": [
                    {
                        "Id": 1,
                        "name": "Batman",
                        "franchise": "DC", 
                        "gender": "Male", 
                        "powers": [{"power":"stealth"},{"power":"intelligence"},{"power":"weaponry"}]
                    },                  
                    {
                        "Id": 2,
                        "name": "Ironman",
                        "franchise": "Marvel", 
                        "gender": "Male", 
                        "powers": [{"power":"flight"},{"power":"intelligence"},{"power":"weaponry"}]
                    },          
                    {
                        "Id": 3,
                        "name": "Supergirl",
                        "franchise": "DC", 
                        "gender": "Female", 
                        "powers": [{"power":"flight"},{"power":"strength"},{"power":"speed"}]
                    },                  
                    {
                        "Id": 4,
                        "name": "Valkyrie",
                        "franchise": "Marvel", 
                        "gender": "Female", 
                        "powers": [{"power":"flight"},{"power":"intelligence"},{"power":"strength"}]
                    }           
                ]
            },
            {
                "Id": 2,
                "hero": [
                    {
                        "Id": 1,
                        "name": "Batwoman",
                        "franchise": "DC", 
                        "gender": "Female", 
                        "powers": [{"power":"stealth"},{"power":"intelligence"},{"power":"weaponry"}]
                    },                  
                    {
                        "Id": 2,
                        "name": "IronPepper",
                        "franchise": "Marvel", 
                        "gender": "Female", 
                        "powers": [{"power":"flight"},{"power":"intelligence"},{"power":"weaponry"}]
                    },              
                    {
                        "Id": 3,
                        "name": "Superman",
                        "franchise": "DC", 
                        "gender": "Male", 
                        "powers": [{"power":"flight"},{"power":"strength"},{"power":"speed"}]
                    },                  
                    {
                        "Id": 4,
                        "name": "Thor",
                        "franchise": "Marvel", 
                        "gender": "Male", 
                        "powers": [{"power":"flight"},{"power":"intelligence"},{"power":"strength"}]
                    }
                ]
            }
        ]
    }
}       

Answer №1

To begin, utilize the flatMap method to consolidate all players into a single list. Next, with your criteria specified as an object, you can filter out players by checking if every property in the criteria matches the player's properties:

function filter(players, criteria) {
  return players.players.groups.flatMap(({Id, hero}) => 
    hero.filter(p =>
      Object.entries(criteria).every(([k, v]) => {
        if (k === 'power') return p.powers.some(({power}) => power === v);
        return p[k] === v;
      }))
      .map(p => ({groupId: Id, ...p}));
}

const oPlayers = {
  "players": {
    "groups": [{
        "Id": 1,
        "hero": [{
            "Id": 1,
            "name": "Batman",
            "franchise": "DC",
            "gender": "Male",
            "powers": [{
              "power": "stealth"
            }, {
              "power": "intelligence"
            }, {
              "power": "weaponry"
            }]
          },
          ...
           ]
      }
    ]
  }
};

console.log(filter(oPlayers, {gender: 'Male', franchise: 'Marvel'}));
console.log(filter(oPlayers, {gender: 'Female', power: 'flight'}));

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 best way to refresh a React ES6 component following an AJAX response?

I'm a beginner in React and ES6, trying to create a search field that fetches data as the user types. I want to make an AJAX call using the fetch API when the user types at least 3 characters in the field. When I run the fetch snippet code in the brow ...

What is the method for retrieving a temporary collection in a callback function when using node-mongodb-native find()?

Is it possible to retrieve a temporary collection from a find() operation instead of just a cursor in node-mongodb-native? I need to perform a mapReduce function on the results of the find() query, like this: client.open(function(err) { client.collect ...

Is there a way to avoid waiting for both observables to arrive and utilize the data from just one observable within the switchmap function?

The code snippet provided below aims to immediately render the student list without waiting for the second observable. However, once the second observable is received, it should verify that the student is not enrolled in all courses before enabling the but ...

What is the reason for the absence of an array length function in the C programming language?

Even though there are numerous methods to determine the length of an array in C, the language itself does not have a built-in function for this task. What could be the rationale behind omitting such a frequently used operation from C and its subsequent ve ...

Generating a multidimensional associative array from a database

I am struggling to create an associative array that looks like this: Array( Array('111.01.0040' => 'PEMBENAHAN PIPA TURBIN'), Array('111.01.0041' => 'PENGELASAN UNVIL'), Array('111.01.00 ...

Exclusive Modal Pop-Up for First-Time Visitors - Utilizing Bootstrap, PHP, and JavaScript

Seeking assistance from the community as I have exhausted my online research efforts. I am currently working on implementing a welcome bootstrap modal in a php environment. Despite being new to php and js, I have managed to make it pop up only once using ...

Tips for evaluating the performance of webGL clients using three.js

Currently, I am working on a graphic project utilizing three.JS and I am interested in automatically assessing the GPU performance of my client's device. This will help me determine the optimal number of elements to load in the application. Essentiall ...

Navigation menus are being highlighted

I'm having trouble figuring out why my program isn't working as expected. The onmouseout event doesn't seem to trigger when hovering over an image in the menu... Check this link for more information Below is the code snippet causing the is ...

Ways to automatically run Java script again when new elements are included in the document model

Recently, I added paging and filtering to a page displaying a list of products. @model ProductFiltersViewModel ... <div class="row"> <aside class="col-3"> <nav class="sidebar card py-2 mb-4"> ...

Combining multer, CSRF protection, and express-validator in a Node.js environment

Within my node.js application, I am utilizing an ejs form that consists of text input fields in need of validation by express-validator, an image file managed by multer, and a hidden input housing a CSRF token (a token present in all other forms within the ...

What is the best way to utilize a single component for validating two other components?

I am encountering an issue with my components setup. I have three components in total: GalleryAddComponent, which is used to add a new element, GalleryItemComponent, used to edit an element, and FieldsComponent, the form component utilized by both GalleryA ...

Error message from Angular stating that the factory function is not recognized as a function within the Controller

I have encountered similar questions in the past, but they often involve missing injections, and I hope that is not the issue in my case. For my current app project, I am attempting to send a GET request to the server to retrieve a list of modules. Contr ...

Using AJAX to send an ID to another HTML page allows for the creation of a unique WHERE clause

UPDATED: MAY 17, 2017 9:50 AM I am currently working on two HTML pages that both utilize AJAX to fetch data upon page load. I now have a requirement where I need to pass an ID from one HTML page to another in order to retrieve specific data using a WHERE ...

Currently focused on designing a dynamic sidebar generation feature and actively working towards resolving the issue of 'Every child in a list must have a distinct "key" prop'

Issue Found Alert: It seems that each child within a list needs a unique "key" prop. Please review the render method of SubmenuComponent. Refer to https://reactjs.org/link/warning-keys for further details. at SubmenuComponent (webpack-internal:///./src/c ...

Make sure to consistently receive the distinct key notice: Every child within a set must possess a unique "key" property

Trying to understand the part of this code that suggests I don't have keys for the pushed array items: import { Accordion, AccordionSummary } from '@material-ui/core' import { createStyles, makeStyles, Theme } from '@material-ui ...

The index type 'X' is not allowed for use in this scenario

I encountered an issue in my TypeScript code: error message: 'Type 'TransitionStyles' cannot be used as an index type.' I'm wondering if there's a way to modify my interface so that it can be used as an index type as well: ...

Tips for updating the display by fetching data from a database through a websocket

I am looking for a solution to update a specific part of my webpage without having to refresh the entire content. On my index.html page, I have three panels displaying various ticket statuses. I want to automatically update the number of resolved tickets s ...

Attempting to retrieve an object's attribute

Hey! I have a question regarding the screenshot in this link: I'm trying to access the user object with the property team. So far, I've attempted using data.Object, but it returns an undefined output. I also tried using data.user but that resul ...

The most effective method for displaying a timestamp in the user's specific timezone using Node.JS

My application logs user events and stores timestamps as dates in Mongo, which are then converted to JS Date objects with timezone information based on the server's timezone. Although I am using moment.js to format the dates, the issue arises because ...

Click on the text next to my checkbox to activate it

I've been attempting to create a situation where the text next to my checkbox is clickable. However, for some reason, the code I'm using doesn't seem to be working as expected. Can anyone help me troubleshoot this issue? <form name="f1"& ...