Matt Ball
Matt Ball

Reputation: 359816

Is there a slicker way of doing this?

I seem to handle special cases like this somewhat frequently. There's got to be a more concise syntax or construct:

var x = solveForX(); /* some slow calculation here */
if (x < 0)
{
    x = 0;
}

This is equivalent, but doesn't feel any more elegant:

var x;
x = (x = solveForX()) < 0 ? 0 : x;

Maybe there's a bit shift trick?


Update: I ran some benchmarks to compare my two favorite answers - the one I accepted, and Peter Ajtai's. Turns out Peter's is quite a bit faster! Running 1,000,000 iterations of each (I also ran a version that caches Math.max to see how much time the lookup contributed) shows that Peter's runs in under half the time of the Math.max version, even with max caching.

That said, even the "slowest" method is still quite fast.

Upvotes: 16

Views: 711

Answers (6)

Otroberts
Otroberts

Reputation: 347

I think that this way is pretty nice!

var x = Math.max(solveForX(), 0);

Good luck!

Upvotes: 0

s4y
s4y

Reputation: 51685

The accepted answer is perfect. If you want to accomplish the same without a function call, I believe that this is most concise:

var x;
(x = solveForX()) > 0 || (x = 0);

(In Safari, this implementation is a whole 7% faster than Math.max(), which is probably not worth caring about)

Upvotes: 0

Peter Ajtai
Peter Ajtai

Reputation: 57685

(x < 0) && (x = 0);

Edit: Removed the if statement. Thanks Andreas.

This is one line, and it's clear what it does (in my personal opinion) - if you're familiar with boolean short circuit evaluation.

The above makes use of boolean short circuit evaluation. This can be very useful in certain situations (especially pointer arithmetic in C++, but boolean short circuit evaluation also works in Javascript).

x = 0 only evaluates if x < 0.

Here are two examples:

This alerts 1:

<script type="text/javascript">
    var x = 1;
    (x < 0) && (x = 0);
    alert(x);
</script>

This alerts 0:

<script type="text/javascript">
    var x = -1;
    (x < 0) && (x = 0);
    alert(x);
</script>

Upvotes: 8

viam0Zah
viam0Zah

Reputation: 26312

I'd decorate the original solveForX function.

function returnNonNegative(fn) {
    function _f() {
        var x = fn();
        if (x < 0) {
            x = 0;
        }
        return x;
    }
    return _f;
}

solveForX = returnNonNegative(solveForX);

In this particular case, using Math.max seems to be fine, but this pattern provides a generic solution for this type of problems.

Upvotes: 2

Dave McClelland
Dave McClelland

Reputation: 3413

How about

var x = Math.max(solveForX(), 0);

Upvotes: 29

Vladimir
Vladimir

Reputation: 170839

Something like:

x = Math.max(0, solveForX());

Upvotes: 10

Related Questions