Strategies for sorting through arrays of objects containing nested objects with defined properties?

I'm facing an issue while filtering a Javascript array of objects with nested objects based on specific properties. I can successfully filter by name, slug, website, and launch year without any problem. However, when it comes to filtering the category name (category.name) which is inside the object, it doesn't seem to work. Why does the filter for category name fail?

            var search = "qui"; // doesn't work (category.name)
            // var search = "Sauer"; // works (name)

            var data = [{ "name": "Sauer-Metz", "slug": "ab-laborum", 
              "website": "https://test.com", "launch_year": 2017,  "category_id": 6,
              "category": { "id": 6, "name": "qui", "slug": "qui" } } ];

            var results = data.filter(company => [
                'name', 'launch_year', 'website', 'category.name'
            ].some(key => String(company[key]).toLowerCase().includes(search.toLowerCase())));

            console.log(results);

Answer №1

To tackle this issue, one effective approach is to utilize a value extractor similar to the function getKey shown below:

const getKey = (value, key) => {
    return key.split('.').reduce((acc, curr) => value[curr], '');
}

var filteredResults = data.filter(company => [
        'name', 'launch_year', 'website', 'category.name'
    ].some(key => String(getKey(company, key)).toLowerCase().includes(search.toLowerCase())));

Answer №2

In my opinion, in order to address this specific nested property, it seems necessary to create a separate condition. Although I am currently unable to identify a more efficient approach:

let filteredResults = data.filter(
  (company) =>
    ["name", "launch_year", "website"].some((key) =>
      String(company[key]).toLowerCase().includes(search.toLowerCase())
    ) ||
    String(company["category"]["name"])
      .toLowerCase()
      .includes(search.toLowerCase())
);

Answer №3

The dot notation operates differently than expected.

const testCase1 = 'apple';
const testCase2 = 'banana';

const info = [
    {
        name: 'Banana Split',
        description: 'A tasty treat',
        price: 5.99,
        category_id: 3,
        category: { id: 3, type: 'fruit', color: 'yellow' },
    },
];

const searchItems = (data, word) => {
    return data.filter((item) => {
        return (
            item?.category?.type.toLowerCase().includes(word.toLowerCase()) ||
            ['name', 'price', 'description'].some((key) => `${item[key]}`.toLowerCase().includes(word.toLowerCase()))
        );
    });
};

console.log('**SCENARIO A**')
console.log(searchItems(info, testCase1));
console.log('**SCENARIO B**')
console.log(searchItems(info, testCase2));

Answer №4

If you want to implement your method, you can change 'category.name' into ['category','name'], and then utilize

String(company[key[0]][key[1]])...
whenever the key is an array.

const search = "qui"; // does not work (category.name)
//const search = "Sauer"; // works (name)

const data = [{ "name": "Sauer-Metz", "slug": "ab-laborum",  "website": "https://test.com", "launch_year": 2017,  "category_id": 6, "category": { "id": 6, "name": "qui", "slug": "qui" } } ];

const results = data.filter(
    company => [
        'name', 'launch_year', 'website', ['category','name']
    ].some(
        key => 
        Array.isArray(key) ?
        String(company[key[0]][key[1]]).toLowerCase().includes(search.toLowerCase()) : 
        String(company[key]).toLowerCase().includes(search.toLowerCase())
    )
);

console.log(results);

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 value on the input of a custom Vue component does not update as expected when using v

I'm currently working on a custom component called customCombobox. It functions similarly to a regular v-combobox, but with an added feature - after the user presses the tab key, it automatically selects the first option available. Everything in my i ...

Visualizing JSON data on D3.js graph axis

Below is a snippet of JSON data that I successfully plotted on a d3js graph, using it as the x and y axis: var data = [ { "count": "202", "year": "1590" }, { "count": "215", "year": "1592" }, { "count": "179", "year": "1593" } ]; Now, I am facing a chal ...

Check if an array includes a specific value, and then either update it if found, or create it

I'm currently working with a Cart object in Javascript and I need to check if a specific item is present in the cart. Here's my approach: If the item is already in the cart, update its quantity. If it's not in the cart, add it to the items ...

Trouble with Firebase import despite successful installation

I attempted to create a basic website to gain knowledge about Firebase 9, but I am facing issues when trying to import firebase files. I have searched for tutorials on configuring firebase, but they either do not address my problem or are based on older v ...

Utilize try-catch or async-await within useEffect when testing with Jest

I am currently setting up my initial unit tests using JEST. I've installed Jest Fetch Mock but unfortunately, I keep encountering an error stating "The promise rejected with reason FetchError". After doing some research, it seems like I may need to i ...

Ensuring the server application is up and running before initiating the mocha tests

This is similar to Ensuring Express App is running before each Mocha Test , but the proposed solution isn't effective + I am utilizing a websocket server In essence, I'm making use of a websocket framework called socketcluster and this represent ...

Sending selected value from Mat-Select to header during API Call: A step-by-step guide

I'm dealing with an API that requires the country code in the header along with an authorization token and Bearer. In my component file, I am able to fetch the value from a mat-select dropdown. However, the setting for the API header and token is done ...

The next() function is malfunctioning in Express 4, resulting in the following error message: "Error [ERR_HTTP_HEADERS_SENT]: Headers cannot be set after they have

I've been learning ExpressJS, but the next() function is not working. Can anyone please help me with this issue? Currently, I am following an online course on Udemy that covers Express JS. I have written my code exactly like the instructor's, bu ...

Like button for Facebook located at the bottom of a static webpage

I am facing an issue with my web application where it does not scroll properly, especially when there is a Facebook button at the bottom. The behavior in Chrome and Firefox is inconsistent and causing some trouble. In Chrome, the div repositions correctly ...

Listening for events from an iframe can be achieved using a jQuery event listener on the parent element. However, transitioning to using

I'm exploring various methods to attach event listeners for custom events from an iFrame. While I can effectively listen to events from the iFrame using jQuery, I seem to face difficulties achieving the same with plain JavaScript code. I would greatl ...

Changing a class on an element when clicked using Angular.js

Is there a way in angular.js to toggle a css class active on and off when clicking on an element? I am familiar with using ng-class and ng-click, but how can I refer to the element itself? For instance, if I have three buttons: <a class="btn" ng-clic ...

Creating a square shape using JavaScript

I'm working on a JavaScript project where I need to create a square element. In my CSS, I have defined a class for squares. I want to implement something like <div class="square></div> so that the square appears when a button is clicked. I ...

Scattering a 3D array in MPI to form tetragonal prisms

Greetings to all! I am currently working on scattering a 3D array in a tetragonal prism format. To help you visualize, check out the image below: Imagine the large cube as a 3D array (let's say with dimensions of 4x4x4) and processors P0..P3 assigned ...

Hovering over an image and trying to rotate it results in

Check out my rotating image example on hover in React here This effect utilizes scale(), rotate(), and transition properties to create an animated rotation when hovering over the parent element. Additionally, overflow: hidden is applied to the parent elem ...

Is there a more efficient method for storing JSON values as an Array in my code?

Let me share my approach: <script> function games(){ document.write("loading"); $.ajax({ url: "http://allencoded.com/test3.php", dataType: 'json', success: function (data) { var homeTeams = new Array(); for (var i ...

The constructor error in ng-serve signalizes an issue in

Currently, I am developing an AngularJS application. However, when attempting to start the dev server, I encountered an issue with my ng serve command: https://i.stack.imgur.com/QujSe.png ...

The program encountered an issue with accessing the 'ref' property, as it was not defined

While creating a basic web app using Vue, Firebase, and Vuefire, I encountered an issue where I received an error message saying "Uncaught TypeError: Cannot read property 'ref' of undefined" when attempting to access my Firebase db variable withi ...

Node child_process causing stdout buffering problems

I am currently facing an issue while attempting to run curl using node child_process in order to retrieve a JSON file (approximately 220Ko) from a shared folder within a local network. However, I am encountering a buffer problem that seems to be causing so ...

What makes it feasible to modify characters in a character array, but not in a char pointer?

Why is it that when I declare an array of characters (char str[]), I can change any of the characters inside, but if I declare the array like this - char* str="abcd";, it's impossible to change any character? Shouldn't they both be the same thing ...

Executing multiple Ajax requests on CodeIgniter 3 from two separate pages

I am facing a critical need for a code review and unfortunately, I am unsure of where else to seek assistance besides here. Let me outline my current task: I am working on a user profile page that is designed to showcase users' comments. Users have t ...