4

I'm trying to create a function that will run through an array and collect it's value to a string that looks like this: '[1,2,3]'. I also need it to present only part of the array in some cases, according to a given index. For example: the array [1,2,0] printed from index 0 to index 1 will look like this: '[1,2]'. For some reason my function don't give any output at all. Here it is:

function Tower(size, isFull) {
    this.count = 0;
    this.tower = new Array(size);

    this.add = function(disk) {
        this.tower[this.count++] = disk;
    };

    if (isFull) {
        for (var i = 1; i <= size; i++) {
            this.add(i);
        };
    }

    this.canAdd = function(disk) {
        return this.count == 0 || this.tower[this.count - 1] > disk;
    };

    this.getTopDiskValue = function() {
        return (this.count > 0) ? this.tower[this.count - 1] : 0;
    };

    this.popTop = function() {
        return this.tower[--this.count];
    };

    this.isFull = function() {
        return this.count == this.tower.length;
    };

    this.printable = function() {
        var output = "[";
        for (var i = 0; i < this.count; i++) {
            output += "" + this.tower[i] + ',';
        }
        return output.substring(0, output.length() - 1) + (output.length() > 1 ? ']' : "");
    };
}

I expect the printable() function to return the string so that the code:

var tower = new Tower(3,true);
alert(tower.printable());

will pop an alert box with the text '[1,2,3]' on it. This object is a translation from Java. It worked great in java btw, I guess the translation is not perfect.

1
  • Check your error console and you will see the reason. Commented Oct 1, 2012 at 16:51

3 Answers 3

2

What you do is much too complicated.

Let's say you have an array declared as

var array = [1, 2, 3];

you get the desired string with

return '['+array.join(',')+']';

You don't need pop or add functions, they're also native (and heavily optimized) :

var last = array.pop()
array.push(newItem);

Reference :

Note that all browsers offer a console, in which you'll find a detailed explanation of your errors. Have a look for example at the Chrome Developer Tools.

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

1 Comment

BTW about pop and push methods, I agree, but I was translating the code from Java and didn't want to start optimizing it at this point. The time will come to that :)
1

JavaScript is not Java - you don't get the length of an array or string by calling its .length() method, but just by retrieving its .length property. The exception which is thrown when you try to invoke the number is what crashes your script and prevents the alert. This would work:

this.printable = function() {
    var output = "[";
    for (var i = 0; i < this.count; i++) {
        output += "" + this.tower[i] + ',';
    }
    return output.substring(0, output.length - 1) + (output.length > 1 ? ']' : "");
};

However, you just can use the native .join() method to concatenate the array's values. Also, you should add your methods on the prototype of your Tower objects:

Tower.prototype.printable = function() {
    if (this.count)
        return "[" + this.tower.slice(0, this.count).join(",") + "]";
    else
        return "";
};

Btw: Usually this method is named toString - not only for convenience, but also it would get used when a Tower object is casted to a string value.

4 Comments

Thanks a lot. I usually call this method toString but tried to change it thinking it may cause the problem... XP About adding the method to the prototype - isn't writing the method in the constructor equivalent to adding it to the prototype?
Check out Use of 'prototype' vs. 'this' in Javascript? and the related answers I've linked in my comment there
So if I understand correctly, it boils down to wasting memory?
Yes, and that's bad practise. But the greater advantage is the inheritance from an object that can be dynamically changed - add/change a property on the prototype and all instances can use it
1

use the Array.join() method:

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/join


this.printable = function() {
    var output = new Array();
    for (var i = 0; i < this.count; i++) {
        output.push(this.tower[i]);
    }
    return output.length == 0 
        ? "" 
        : "[" + output.join(",") + ']';
};

or if it's as simple as it looks:

this.printable = function() {
    return this.count == 0 
        ? "" 
        : "[" + this.tower.join(",") + ']';
};

Comments

Your Answer

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