Selecting the optimal data structure: weighing the benefits of using boolean check versus array .include (balancing performance and redundancy

My objects can have one or more properties assigned, with a total of 5 different properties in my case.

To illustrate this, let's use a simple movie example where each movie can be assigned from 5 different genres.

I have come up with two methods to approach this:

  • Assign a boolean for each property of every object individually OR
  • Create an array containing the list of assigned properties for each object

Here are the options:

Option 1:

[{id: 1, name: 'some movie 1', comedy: true, thriller: true, drama: true, action: false, adventure: true},
{id: 2, name: 'some movie 2', comedy: false, thriller: true, drama: false, action: false, adventure: false},
{id: 3, name: 'some movie 3', comedy: true, thriller: true, drama: true, action: false, adventure: true},
{id: 4, name: 'some movie 4', comedy: true, thriller: true, drama: true, action: false, adventure: false}, ...]

Option 2:

[{id: 1, name: 'some movie 1', genre: ['comedy','thriller','drama']},
{id: 2, name: 'some movie 2', genre: ['thriller','drama']},
{id: 3, name: 'some movie 3', genre: ['comedy','thriller','adventure']},
{id: 4, name: 'some movie 4', genre: ['comedy','thriller']}, ...]

Personally, I prefer option 2 as it is more concise and does not store redundant data (false boolean values).

However, I am concerned about the performance implications. Using .include() to check arrays seems slower compared to a simple boolean check as seen in option 1.

This leads me to a dilemma between redundancy and performance. Is there a better solution that could address this issue like using a different data structure?

Thank you in advance!

Answer №1

When working with option 1, it's not necessary to explicitly define the false properties. Simply leave them as undefined, which is considered a falsy value.

const movies = [
  {id: 1, name: 'some movie 1', comedy: true, thriller: true, drama: true, adventure: true},
  {id: 2, name: 'some movie 2', thriller: true},
  {id: 3, name: 'some movie 3', comedy: true, thriller: true, drama: true, adventure: true},
  {id: 4, name: 'some movie 4', comedy: true, thriller: true, drama: true,}
];

const comedies = movies.filter(m => m.comedy);

console.log(comedies);

By following this approach, unnecessary data redundancy is eliminated without compromising filtering performance.

Answer №2

Instead of having multiple keys for genres, consider using a single key with an integer representing different genres as flags:

comedy  drama   something else  
   1      0            1       === 1 * 2^2 + 0 * 2^1 + 1 === 5

This way you can simplify your data structure like this:

{
    id:1,
    name: "some",
    genre: 5
}

To check if 'comedy' is included in the genres, you would do:

(genre ^ 4) === (genre - 4)

For checking 'drama', it would be:

(5 ^ 2) === (5 - 2) //false

You have the flexibility to use bitmasking genre & 4 as well, according to your preference.

Answer №3

It is not recommended to perform extensive data filtering on the client side. This can lead to slow computation of large datasets, causing the main browser thread to block and resulting in UI lag and slowdowns. The ideal approach is to establish a server with an API dedicated to handling such filtering tasks independently from the client. By querying the API, you can easily retrieve the filtered data without impacting client-side performance. If excessive data filtering on the client becomes a performance issue, it indicates a flaw in the app's structure.

If for some reason filtering must be done on the client side, utilizing a WebWorker is advised. This allows the filtering to occur in a background thread without affecting the UI responsiveness.

However, performing client-side filtering (with or without WebWorker) may encounter challenges across different browsers due to varying JavaScript implementations. Benchmarking different methods can help determine the most efficient approach. I conducted a benchmark test here which showcases differences in performance between Chrome, Firefox, and Safari.

https://i.stack.imgur.com/X1mLb.png

The results reveal that each browser, based on its JavaScript engine (V8, SpiderMonkey, Webkit), exhibits different speeds. For optimal performance across browsers, Array.includes() emerges as a reliable choice, displaying strong results in Chrome, decent performance in Firefox, and good performance in Safari.

Conclusion:

  1. Create an API for filtering tasks whenever possible
  2. If client-side filtering is necessary, utilize a WebWorker
  3. For best results, consider using Array.includes()

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

Leveraging Angular to retrieve images from Google Feed API

I'm currently working on developing an RSS reader and trying to integrate images from the Google Feed API. While I have successfully extracted the publishedDate and contentSnippet, I am facing difficulty in getting the image src. The code snippets bel ...

Retrieve the link of a nearby element

My goal is to create a userscript that has the following functionalities: Add a checkbox next to each hyperlink When the checkbox is clicked, change the state of the corresponding hyperlink to "visited" by changing its color from blue to violet. However ...

Updating a singular value in an array using jQuery/JavaScript

Within a Javascript function, I have created an array called HM_Array1. The contents of the array are listed below: HM_Array1 = [[,11,147,,,,,,,1,1,0,0,0,1,"csiSetBorder(this)","null",,,true,["   Accoun  & ...

Having trouble injecting ActivatedRouteSnapshot into the component

Struggling to inject ActivatedRouteSnapshot into a component, encountering errors when trying to access query params. Here is the error stack trace: "Error: Can't resolve all parameters for ActivatedRouteSnapshot: (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?). a ...

Enliven the character limit reaction by incorporating a thrilling shake animation when it reaches

I have implemented a feature in my component where if a user reaches the character limit, the component should shake. However, despite my efforts, the shaking effect is not working in the current code. const useStyles = makeStyles(() => ({ shake ...

Dealing with website links in Next.js and Chakra-UI: Tips and Tricks

When incorporating react linkify directly with chakra-ui components such as Text, the links cannot be managed. Issue Example import Linkify from 'react-linkify'; import {Box, Text} from '@chakra-ui/react'; export default function Usag ...

Guide for using two Async Pipe functions in Angular 7

Two different functions are in place to check a specific condition, and the requirement is for both of them to be true simultaneously. How can *ngIf be utilized to achieve this? Currently, setting just one of them works, but the aim is to have both. HTML ...

Using jQuery and AJAX to send a post request in a Razor page and automatically redirect to the view returned by a MVC Action (similar to submitting

I send a json array to the MVC Action using either JQuery or Ajax, and the Action processes the request correctly. However, when the MVC Action returns a View, I am unsure of how to redirect to this View or replace the body with it. Overall, everything se ...

The Angular router is directed to an empty URL path instead of the specified URL

I have encountered a strange issue while developing my angular app which involves the router functionality. All routes were working perfectly fine until I discovered that after a successful login, instead of navigating to the '/admin' path as int ...

Ways to create a looping mechanism with specified number restrictions and limitations

Can anyone assist me with this problem? I am looking to create a "looping" effect similar to the image provided. What is the logic behind this repetition? Thank you in advance for your help! Here is an example output: ...

I'm looking to eliminate the index from an array containing elements with a minimum length of 3 characters

Here is an array that needs to have indexes removed if they are less than 3 characters in length: Array ( [0] => #FCBayern [1] => won [2] => a [3] => Championsleague [4] => match [5] => with [6] => 2 [7] => goals ...

Having trouble with retrieving JSONP data? Unsure how to access the information?

Why do I keep getting a -403 error? https://i.stack.imgur.com/T53O9.png However, when I click on the link, I see this: https://i.stack.imgur.com/8GiMo.png How can I retrieve the message? ...

Loading an external javascript file dynamically within an Angular component

Currently, I'm in the process of developing an Angular application with Angular 4 and CLI. One of my challenges is integrating the SkyScanner search widget into a specific component. For reference, you can check out this Skyscanner Widget Example. T ...

What is the best way to pass a mask without using a plug-in when dealing with an input value in Vue.js?

As someone who has previously implemented the function using pure JavaScript, I am now faced with the challenge of incorporating it into vue.js and determining which lifecycle hooks are best suited for this task. This issue arises as I am a beginner prepar ...

Determine whether a value contains a minimum of two words or more using JavaScript

When users input their names into a field and submit it, I want to make sure that I receive both their first and last names. In order to do this, I need to check if the value contains at least two words. However, the current code I am using does not seem ...

I created a thorough duplicate that successfully addressed an issue with a table

Currently, I am facing an issue with the material-table library as it automatically adds a new element called tableData to my object when I update it using Patch in my code and API. To resolve this problem, I tried implementing both a conventional and cust ...

Dispatch a websocket communication from a synchronous function and retrieve the information within the function itself

I am currently working on an Angular project and need guidance on the most effective approach to implement the following. The requirement is: To retrieve an image from the cache if available, otherwise fetch it from a web socket server. I have managed ...

Each time a new client connects, socket.io replicates the information

Exploring Node.js and socket.io for the first time, I have developed a small application where a table is meant to be displayed in real-time via socket.io when a function is triggered through a websocket (function triggers an "emit"). However, I'm fac ...

Learn the steps for filling the color area between two points in HighCharts

Is it possible to have a color fill between two points on an area chart when clicked? You can view the current chart here. $(function () { $('#container').highcharts({ chart: { type: & ...

Activate the Masterpage menu to emphasize its current state

I am currently utilizing the AdminLTE template on my website. One issue I have encountered is with the menu and its child menus. When redirecting to different pages using image buttons, the menu collapses back to its original state. While navigating throu ...