Charles
Charles

Reputation: 53

Using the conditions value in if/else

I'm wondering if it's possible to access a condition's value directly like the following example.

var a = ["pear", "kiwi", "orange", "apple"]
if(a.indexOf("orange") !== -1){
  console.log(this) //as a.indexOf("orange") has been evaluated already above this prints 2
}

This would also make ternary operators less bloaty

var a = ["pear", "kiwi", "orange", "apple"]
var b = ((a.indexOf("orange") !== -1) ? this : '') //"this" equals 2

Thanks

EDIT: Clearing this question up for any future visitors. Basically this question is about retrieving the resulting value of what is evaluated in an if/else statement. In the example of

var a = ["pear", "kiwi", "orange", "apple"]
if(a.indexOf("orange") !== -1){ //is basically if(2 !== -1)
  console.log(this) //would then be "2" from the already evaluted a.indexOf from above
}

Upvotes: 5

Views: 155

Answers (7)

aw04
aw04

Reputation: 11177

You can simply store it before the statement if the goal is to not evaluate twice. The answer to your literal question is no.

const orangeIndex = a.indexOf("orange")

if (orangeIndex !== -1) {
  console.log(orangeIndex)
}

Same concept applies to the ternary operator.

As others have shown, you can also declare a variable and do the actual assignment in the if statement itself, but IMO this makes your code less readable without adding any value.

Upvotes: 6

joelnet
joelnet

Reputation: 14241

You can accomplish this through memoization. lodash provides a method to do this called memoize.

Creates a function that memoizes the result of func. If resolver is provided, it determines the cache key for storing the result based on the arguments provided to the memoized function. By default, the first argument provided to the memoized function is used as the map cache key. The func is invoked with the this binding of the memoized function.

// your collection
const fruit = ["pear", "kiwi", "orange", "apple"]

/*
 * a basic indexOf function that we can memoize.
 * @example
 * indexOf(fruit)('kiwi') // 1
 */
const indexOf = list => Array.prototype.indexOf.bind(list)

/*
 * a memoized version of IndexOf that is seeded with the list
 * @example
 * memoizedIndexOfA('kiwi') // 1
 */
const memoizedIndexOfA = _.memoize(indexOf(fruit))

// the first time it is called in the `if` it is calculated
if (memoizedIndexOfA("orange") !== -1){

    // the value was previously calculated, so retrieve from the cache.
    console.log(memoizedIndexOfA("orange"))
}

Upvotes: 0

Pointy
Pointy

Reputation: 413737

There's no implicit facility, but you can assign the comparison value to a variable:

var a = ["pear", "kiwi", "orange", "apple"], result;
if (result = (a.indexOf("orange") !== -1)){
  console.log(result);
}

edit — the same technique can be applied if you just want part of the evaluated expression:

var a = ["pear", "kiwi", "orange", "apple"], result;
if ((result = a.indexOf("orange")) !== -1){
  console.log(result);
}

Now the .indexOf() return value is retained in result instead of the comparison result.

Upvotes: 4

Barmar
Barmar

Reputation: 781068

If you want really terse code, you can assign a variable within the condition.

var orangeIndex;
var a = ["pear", "kiwi", "orange", "apple"];
if ((orangeIndex = a.indexOf("orange")) !== -1) {
  console.log(orangeIndex);
}

You can also do it in a ternary:

var orangeIndex;
var a = ["pear", "kiwi", "orange", "apple"]
var b = (((orangeIndex = a.indexOf("orange")) !== -1) ? orangeIndex : '');
console.log(b);

In both cases, don't forget the parentheses around the assignment. This is needed because assignment has lower precedence than comparison operators, so it would otherwise set the variable to true or false.

Upvotes: 2

viktarpunko
viktarpunko

Reputation: 353

I refactor your code. You can hold result of condition in a variable.

var a = ["pear", "kiwi", "orange", "apple"];

var isOrange = a.indexOf("orange") !== -1;

if(isOrange){
  console.log(this) //as a.indexOf("orange") has been evaluated already above this prints 2
}

var a = ["pear", "kiwi", "orange", "apple"]
var b = isOrange ? this : '') //"this" equals 2

Upvotes: 0

RamblinRose
RamblinRose

Reputation: 4963

This is as close as it gets

var a = ["pear", "kiwi", "orange", "apple"], result;
if ((result = a.indexOf("orange")) !== -1) {
  console.log(result);
}

Here, @result = the index rather than the result of the logical operation that Pointy offered.

Upvotes: 0

Lajos Arpad
Lajos Arpad

Reputation: 76551

Yes, this is in fact very simple. Example

if (yourvariable = yourcondition) {
    //Do something
} else if (yourvariable2 = yourcondition2) {
    //Do something else
} else if ((yourvariable3 = yourcondition3) || true) { //This is an else, but you memorized a condition inside it
    //Do something
}

When you assign a value to a variable, then the variable will hold that value and also, the result of the operator will be the value, therefore

if (foo = bar) {
    //Some operations
}

is equivalent logically to

if (bar) {
    foo = bar;
    //Some operations
}

but it is longer and if bar happens to be a function with a lot of operations, then it is not ideal to evaluate it twice.

Upvotes: 0

Related Questions