4

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?

3
  • @blex why is it evil? Is it slow? Commented Jun 26, 2015 at 21:13
  • 1
    @blex thanks this works! If you want to provide answer I will accept Commented Jun 26, 2015 at 21:16
  • Thanks Chowza. If you want to avoid using eval or a big switch statement, I've found an alternative way, check my edited answer. Commented Jun 26, 2015 at 22:00

2 Answers 2

8

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)) {

        }
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

It is the same logic of other answer, why repeat it again?
Hash is more handy, than switch. And allow to parametrize function without editing function body.
I've decided to change the accepted answer to this one as I find this to be easier to use, ie you can also use it to compare strings etc
1

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);
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.