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.

3 Answers3

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.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 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 :) –  Oct 01 '12 at 20:52
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(",") + ']';
};
hunter
  • 62,308
  • 19
  • 113
  • 113
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.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 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? –  Oct 01 '12 at 17:36
  • Check out [Use of 'prototype' vs. 'this' in Javascript?](http://stackoverflow.com/q/310870/1048572) and the related answers I've linked in my comment there – Bergi Oct 01 '12 at 18:00
  • So if I understand correctly, it boils down to wasting memory? –  Oct 01 '12 at 20:53
  • 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 – Bergi Oct 01 '12 at 21:03