0

For example, can I create a method which can return me an expression that can be evaluated by if?

function getCondition(variable, value, operator)//not sure what params to pass
{
   var condition = false; //initialized to false
   //generate condition based on parameter passed
   return condition;
}

and then use it directly

if ( getCondition( a, 5, "<" ) ){ console.log("correct") }
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
  • actually the problem is more along the lines of `if (doesThisGetEvaluatedImmediately()) { // bla... }`. It does and its return value is either used as is (if boolean) or converted to boolean. – Andrei C Mar 01 '16 at 09:12

6 Answers6

2

Yes.

In your example, which probably is not your actual use-case, you'd simply have to map your operator:

function getCondition( x, y, op ) {
  switch ( op ) {
    case '<':
      return x < y
    case '>':
      return x > y
    default:
      throw new Error( 'operator not understood' )
  }
}

if ( getCondition( 1, 5, '<' ) ) {
  ...
}

You might see this pattern commonly in something like a physics simulation, where you need operators that do not exist natively, such as dot or cross products. I've never seen a use-case where you'd want to pass that operator explicitly to a function though, rather, just create the functions you need for each operator.

Matt Styles
  • 2,442
  • 1
  • 18
  • 23
1

You could pass the expression as a parameter

var a = 3.5;

function getCondition(bool) {
    var condition = false;
    return bool || condition
}

if (getCondition(a < 5)) {
  console.log("correct")
}
guest271314
  • 1
  • 15
  • 104
  • 177
  • Well, question is - Did i have to call the method if I can use the condition itself? Hope this was not a troll answer :) I am just looking for a way to generate the condition itself. Thanks anyways, looks like it is not possible and Matt's answer is the best that could be done. – gurvinder372 Mar 01 '16 at 09:25
  • @gurvinder372 See also http://stackoverflow.com/questions/31040306/sprintf-equivalent-for-client-side-javascript/ , http://stackoverflow.com/questions/32982719/chrome-app-doing-maths-from-a-string/ , http://stackoverflow.com/questions/34735452/terminate-javascript-without-error-exception/ – guest271314 Mar 01 '16 at 10:31
  • @gurvinder372 You could also use `eval()` ; `var a = 3.5; function getCondition(variable, value, operator) { var condition = false; //initialized to false var bool = eval(variable + operator + value); return bool || condition; } if ( getCondition( a, 5, "<" ) ){ console.log("correct") }` – guest271314 Mar 01 '16 at 10:38
  • Thanks for the links. Would you recommend `eval()` for this? – gurvinder372 Mar 01 '16 at 11:55
  • @gurvinder372 You are calling the method that you have created; there is less chance that you would execute malicious commands against yourself. If the method is only to evaluate `<` , `>` conditions, not certain how using `eval()` could return unexpected results ? It depends on what you are actually attempting to accomplish with delaying processing the result of an expression that returns a `Boolean` ; or if there is more to the `javascript` than appears at Question. Will `getCondition` only evaluate integers ? – guest271314 Mar 01 '16 at 16:56
1

You probably want to evaluate arguments when you apply the condition, not when you define it. Here's one possibility:

var operator = {};

operator.greaterThan = function(val) {
    return function(x) {
        return x > val;
    }
};

operator.lessThan = function(val) {
    return function(x) {
        return x < val;
    }
};

isLessThan5 = operator.lessThan(5);


a = 4;
if(isLessThan5(a)) console.log('ok'); else console.log('not ok');

b = 10;
if(isLessThan5(b)) console.log('ok'); else console.log('not ok');

For complex conditions you can also add boolean operators:

operator.and = function() {
    var fns = [].slice.call(arguments);
    return function(x) {
        return fns.every(f => f(x));
    }
};

operator.or = function() {
    var fns = [].slice.call(arguments);
    return function(x) {
        return fns.some(f => f(x));
    }
};

isBetween5and10 = operator.and(
    operator.greaterThan(5),
    operator.lessThan(10));


if(isBetween5and10(8)) console.log('ok')
if(isBetween5and10(15)) console.log('ok')
georg
  • 211,518
  • 52
  • 313
  • 390
  • Thanks, this is closer to what I was looking for. This is much cleaner than using switch case. Can you please let me know what could I have mentioned in my OP so that I could have got response like this? – gurvinder372 Mar 01 '16 at 09:42
  • 1
    @gurvinder372: I guess you should have made the point clear that you want to define a condition first and evaluate it later on. – georg Mar 01 '16 at 09:44
0

Yes, but you have to define in the function what the operator means. So your function needs to contain some code along the lines of:

if (operator === '>') {
    condition = (value1 > value2);
}

You could also use string concatenation and eval, but I wouldn't recommend it:

condition = eval(value1 + operator + value2);
KWeiss
  • 2,954
  • 3
  • 21
  • 37
0

Yes, you can use the return value of a method if it can be evaluated to either true or false.

The sample code you provided should work as you expect it.

The return value of the method can also be evaluated from an int or a string to a boolean value. Read more about that here: JS Type Coercion

Andrei C
  • 768
  • 9
  • 21
0

It is possible to pass a function or expression to an if. Like you're saying yourself, an if accepts an expression... that evaluates to either true or false. So you can create any function or method that returns a boolean value (not entirely true in PHP and other weak typed languages).

Clearly, since PHP isn't strongly typed, no function guarantees that it returns a boolean value, so you need to implement this properly yourself, as doing this makes you prone to getting errors.

Glubus
  • 2,819
  • 1
  • 12
  • 26