Macobo
Macobo

Reputation: 75

Evaluating an object false within a conditional

Let's suppose we have defined a queue object and we want to loop while there are items in the queue.

The obvious solution:

var queue = new Queue();
// populate queue
while (queue.size()) {
    queue.pop();
}

The desired form:

var queue = new Queue();
// populate queue
while (queue) { // should stop when queue's size is 0
    queue.pop();
}

Is it possible to achieve this (exact) syntax showed in the second example javascript? If so, how?

Upvotes: 1

Views: 117

Answers (5)

Jack
Jack

Reputation: 15872

Either of these will work:

Destroy the Queue thus meeting the conditional requirement

var queue = new Queue();
while (queue) {
  queue.size() ? queue.pop() : queue = null;  
}​

Manually break out of the loop

var queue = new Queue();
while (queue) {
  queue.size() ? queue.pop() : break;  
}​

Upvotes: 0

Michael Antipin
Michael Antipin

Reputation: 3532

Is it possible to achieve this (exact) syntax

My answer is: No.

I tried the following to solve the riddle, and it doesn't seem to work.
Yet I think this is the way to go.

Disclaimer: this is just some puzzle-solving, and not the real-world code.

var Queue = function () {};
Queue.prototype.sizeValue = 2;
Queue.prototype.size = function () 
{
    return this.sizeValue;
};
Queue.prototype.pop = function () 
{
    // EDIT: yes, it's not popping anything.
    // it just reduces size to make toString()
    // and valueOf() return nulls.
    this.sizeValue -= 1;
};
Queue.prototype.valueOf = function () 
{
    if (this.size() > 0) {
        return this.sizeValue;
    }
    return null;
};
Queue.prototype.toString = function () 
{
    if (this.size() > 0) {
        return "Queue["+this.sizeValue+"]";
    }
    return null;
};


var test = new Queue();
while (test) {
    test.pop();
    if (test.size() < -1) {
        // just to get you out of the loop while testing
        alert("failed");
        break;
    }
}
alert("out:"+test);

Place alerts inside toString() and valueOf() to see that they don't get triggered by the conditional while (test) {}.

Upvotes: 0

Florian Margaine
Florian Margaine

Reputation: 60717

Something like this should work:

function Queue() {}
Queue.prototype.toString = function() {
    // I'm using "this.queue" as if it were an array with your actions
    return !!this.queue.length;
};

var queue = new Queue();

// Populate queue

while ( queue ) {
    queue.pop();
}

The idea is to override toString to return not some string value, but rather a boolean.

Upvotes: 0

Robin Maben
Robin Maben

Reputation: 23054

var MyClass = function(){

   this.CanOperate; 
   //value should be false when nothing can be done with this class instance
};


Use var obj = new MyClass();

while (obj.CanOperate) { 
    ...
}

Upvotes: 0

Joseph
Joseph

Reputation: 119837

Does it have to be an object? Why not use an array?

var queue = [array,of,things,to,do];
while (queue.length) {
    var todo = queue.pop();
    //do something to todo
}

Upvotes: 1

Related Questions