Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

converting string into comparison operator. Possible or not? Javascript

Tags:

javascript

I'm creating a function to filter my javascript objects.

function filter(array,filterName,filterCondition,filterParameter){

    for(var i=0; i< array.length;i++){
        if(array[i][filterName] -<convert FilterCondition here>- filterParameter){

        }
    }

}

and ideally I would like to use it like this:

filter(anArray,"age",">",10)

Is it possible to convert a string comparison operator into a real operator in my if statement?

like image 987
Terence Chow Avatar asked Oct 27 '25 12:10

Terence Chow


2 Answers

For example, you can use hash like this:

function filter(array,filterName,filterCondition,filterParameter){
    var comparisonOperatorsHash = {
        '<': function(a, b) { return a < b; },
        '>': function(a, b) { return a > b; },
        '>=': function(a, b) { return a >= b; },
        '<=': function(a, b) { return a <= b; },
        '==': function(a, b) { return a == b; },
        '===': function(a, b) { return a === b; },
    };

    var comparisonOperator = comparisonOperatorsHash[filterCondition];

    if (comparisonOperator === undefined) {
        // throw error here
    }

    for(var i=0; i< array.length;i++){
        if(comparisonOperator(array[i][filterName], filterParameter)) {

        }
    }
}
like image 51
cassln Avatar answered Oct 29 '25 01:10

cassln


eval is evil, but can do anything. It's considered evil if arbitrary input can be passed to it, like user input. But if you control what's in there, it should be safe. More info here.

So you could do:

function filter(array,filterName,filterCondition,filterParameter){
    var results = [];
    for(var i=0; i< array.length;i++){
        if(eval(array[i][filterName] + filterCondition + filterParameter)){
            results.push(array[i]['name'])
        }
    }
    document.body.innerHTML = 'These guys are older than 10: ' + results.join(', ');
}

var anArray = [
  {'name': 'Patrick', 'age': 8 },
  {'name': 'John', 'age': 12 },
  {'name': 'Debora', 'age': 26 },
  {'name': 'Jenna', 'age': 3 },
  {'name': 'Brandon', 'age': 14 },
];

filter(anArray,"age",">",10);

Edit

I've thought of another way without the eval, or an endless switch statement. The trick here is to create a temporary script tag, that will hold a function to check conditions. This will avoid recompiling your function on every iteration of the loop, as it would with eval.

var conditionScript = document.createElement('script');

function filter(array,filterName,filterCondition,filterParameter){
    var results = [];
    prepareCondition(filterCondition,filterParameter);

    for(var i=0; i< array.length;i++){
        if( evalCondition(array[i][filterName]) ){
            results.push(array[i]['name']);
        }
    }

    document.body.innerHTML = 'These guys are older than 10: ' + results.join(', ');
}

function prepareCondition(filterCondition,filterParameter){
    if(conditionScript.parentNode) document.body.removeChild(conditionScript);
    conditionScript.innerText = 'function evalCondition(value){'
                              + '    return value ' + filterCondition + filterParameter
                              + '}';
    document.body.appendChild(conditionScript);
}

var anArray=[
  {'name': 'Patrick', 'age': 8 },
  {'name': 'John', 'age': 12 },
  {'name': 'Debora', 'age': 26 },
  {'name': 'Jenna', 'age': 3 },
  {'name': 'Brandon', 'age': 14 },
];

filter(anArray,"age",">",10);
    
like image 21
blex Avatar answered Oct 29 '25 00:10

blex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!