JavaScript that creates dynamic conditions

Can anyone suggest a more efficient way to create dynamically generated conditions inside a loop?

Instead of explaining, here's the code sample:

var condition = "data.label == 'Test'";

for (var key in andArray) {
    condition += "&& " + andArray[key];
}

for (var key in orArray) {
    condition += "|| " + orArray[key];
}

var length = dataArray.length;
var result = [];
for (var i = 0; i < length; i++) {
    var data = dataArray[i];
    if (eval(condition)) {
        result.push(obj);
    }
}

I am currently using the eval() function, but it is proving to be too slow. It takes approximately 25ms to execute this code for an array with 200 elements. This is unacceptable as I plan to use it on arrays containing thousands of elements.

Does anyone have any suggestions for a faster alternative?

Answer №1

Instead of relying on string manipulation, I propose an alternative solution that involves combining functions. By using function composition to build code rather than manipulating strings, the approach is likely to be less error-prone and more professional.

In Javascript, you have the ability to work with first-order functions, meaning you can easily pass around and combine predicates - functions that return a boolean value. For instance:

var isLabelTest = function(obj) {
  return obj.label === 'test';
}

Rather than storing conditions as strings, consider storing them as predicate functions instead. You can then create functions that take predicates and produce new predicates:

var binaryAnd = function(predA, predB) {
  return function(obj) {
    return predA(obj) && predB(obj);
  };
};

var binaryOr = function(predA, predB) {
  return function(obj) {
    return predA(obj) || predB(obj);
  };
};

You can also develop functions that take an array of predicates and merge them into a single new predicate:

var and = function(preds) {
  return preds.reduce(binaryAnd, function(obj) {return true;});
};

var or = function(preds) {
  return preds.reduce(binaryOr, function(obj) {return false;});
};

With an "andArray" containing predicates that must all evaluate to true, and an "orArray" with predicates where at least one needs to be true, the following code accomplishes the task:

var results = [];
var combinedPredicate = binaryAnd(and(andArray), or(orArray));
var pushIfCondition = function (obj) {
  results.push(combinedPredicate(obj));
};
dataArray.forEach(pushIfCondition);

Lastly, remember that writing your own functions for combining predicates is not mandatory - libraries like ramda offer more efficient implementations.

Answer №2

To optimize performance, you can create an instance of the new Function() constructor to parse the string only once:

var totalItems = dataList.length;
var output = [];
var customFn = new Function('info', 'return ' + conditionString);

for (var j = 0; j < totalItems; j++) {
    var info = dataList[j];
    if (customFn(info)) {
        output.push(data);
    }
}

Answer №3

Here's a neat little trick that involves utilizing the filter method:

Scenario 1:

> const num = 10
> const rules = []
> rules.push(num > 5)  // true
> rules.push(num % 2 !== 0)  // checking if it's an odd number, which results in "false"
> console.log(rules)
< [true, false]

> rules.filter((rule) => rule === true).length === rules.length
< false  // Not all conditions were met

Scenario 2:

> const num = 7
> const rules = []
> rules.push(num > 5)  // true
> rules.push(num % 2 !== 0)  // true
> console.log(rules)
< [true, true]

> rules.filter((rule) => rule === true).length === rules.length
< true  // All conditions were satisfied

Answer №4

Here's a neat trick:

OR Dynamic Scenario

const scenarios = [false, 0, 'test', 1]; // different scenarios to try

scenarios.reduce((previousScenario, currentScenario) =>  
previousScenario || currentScenario, false)); // => 'test'

I find this method intriguing because it functions like an actual scenario and returns the real value rather than just a boolean.


If you prefer a boolean outcome, you could have utilized:

scenarios.some(scenario => scenario); // => true

For an and scenario, use Array.every instead of .some

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

Content within iframe is failing to load correctly on both Firefox and Internet Explorer browsers

On my website, I have 4 iframes embedded in 4 different tabs. I've noticed that the content is being cropped when viewed on Firefox, but it loads properly when using Chrome. Strangely, if I manually reload the iframe, the content displays correctly. T ...

Using Mongoose to insert a JavaScript object directly into the database

Recently, I've been working on POSTing a JS object through AJAX to the nodejs backend. My goal is to seamlessly insert this js object into my mongoose db without having to manually map each key to the schema. This is what I have currently (a bit clun ...

Having trouble with this ajax code? It's not showing up dynamically

There is a live search bar in my project where the results are filtered as the user types. Each result is a clickable link that should load on the same page, but I'm facing some issues with the implementation. The search functionality is powered by a ...

Issue encountered while submitting form on JQuery Mobile framework

Currently, I am in the process of developing a small web application utilizing JQuery Mobile and Multi Page architecture. The issue arises on my form as the second page. Upon clicking the submit button, an error message is displayed on my console (error i ...

PHP disregards the starting 202

Currently, I am developing a PHP API Client to interact with an ASP.net (C#) API. By employing the following Javascript function, I am successfully able to retrieve the data: $.ajax({ type: "POST", url: "https://www.eastmidlandstrains.co.uk/s ...

How can I set up a jQuery image slider in an ASP.NET webpage?

After trying to implement an image slider on a page that uses a master page, I encountered some issues. In the example provided, the author used a standalone page without a master page and it worked perfectly fine. So, I decided to create a new page withou ...

Retrieve information from server using JavaScript/jQuery and present it on the page

Imagine having a JavaScript file stored in a specific directory on your computer. In that same directory, there is a folder named 'server' which contains three text files. Now, the task is to showcase all three text files (from the 'server& ...

Ways to retrieve information from a specific key

I'm currently facing a challenge accessing specific data objects that are referenced by keys. In this particular scenario, the "applicant" data is nested within an Event object. My goal is to extract this data and create a new object from it. While I ...

Tips for sending multiple variables in a loop as JSON data through an AJAX request

I need assistance with the code below. I am trying to pass the value[i] into a data string in a json ajax post submit. Essentially, my goal is to gather all the checked values in a form and insert them into an existing json data string using ajax. This is ...

Is there a way to showcase AJAX responses in the exact sequence they were dispatched, all without relying on queuing or synchronous requests?

I'm facing a challenge with sending out multiple getJSON() requests to a remote server in order to retrieve images. The issue is that the responses arrive asynchronously, causing them to be displayed in a mixed-up order. While I could make the reques ...

Obtaining the contents of a local directory with JavaScript

Currently, I am attempting to access the contents of a local folder using JavaScript. Despite my efforts with the Filesystem API, an error is consistently appearing: DOMException: It was determined that certain files are unsafe for access within a Web app ...

Modify the ngb-timepicker formatting to output a string instead of an object

I am currently working on modifying ngb-timepicker so that it returns a string instead of an object. Right now, it is returning the following format: { "hour": 13, "minute": 30 } However, I want it to return in this format: "13:30" This is the HTM ...

The npm copy script is not functioning properly on the Windows 8.1 operating system

I am working on a sapui5 project and I need to execute the following npm script from my package.json: "scripts": { "flatten": "copy -r \\dist\\resources\\test\\commonjslib\\* dis ...

Having difficulty passing data manually to createRangeChart in Ag-Grid

Initially, I am passing unprocessed raw data to ag-Grid to populate the grid, resulting in a chart with randomly arranged ages. I now need to sort and process the age data before passing it to my range chart in order to create a sorted chart, while keeping ...

Using hooks for conditional rendering

Background Information : My current project involves creating a form using hooks and rendering components based on the step. Challenge Encountered : I received this error message: "Error: UserFormHooks(...): Nothing was returned from render. This usually ...

Creating an Angular table using reactive forms: a step-by-step guide

After reviewing the HTML snippet provided below, it is evident that there is a table with looping through mat cell using *matCellDef="let model". Inside each cell, there are input fields which are reactive forms. Each row or cell needs to have it ...

I am having trouble with the Annotation Javascript library, it doesn't

After installing annotorious from the GitHub repository and following the code provided in the official documentation, I encountered an issue where the annotations were not displaying on the image as expected. Below is the HTML code that I used: <!DOCTY ...

Adding the Setting component to the Style Manager

I'm struggling to add component settings (traits) into the Style Manager panel section because of insufficient documentation. The way it is demonstrated in the demo is not clear to me. Is there a specific block of code that I should be using? I' ...

Can you explain the distinction between Vue's 'v-on' directive and vue.$on method?

If I have two sibling components set up like this: <div id="root2"> <some-component>First</some-component> <some-component>Second</some-component> </div> ... and these components are coded as follows: Vue.comp ...

Using React Native to integrate a JSON string into a button

I'm currently working on an app to explore the functionality of websockets in react native. I have successfully retrieved data from the websocket in JSON format and can output it to the console using console.log. However, my goal is to display a speci ...