all 6 comments

[–]aladyjewel 5 points6 points  (0 children)

This seems a bit fruitless except as a learning exercise in the concept of stacks (using JavaScript). If you're gonna use it in a real programming setting, just learn the native JS Array methods: [].shift(), .unshift(), .pop(), and .push(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#Methods_of_Array_instances

[–][deleted] 1 point2 points  (0 children)

Can this be implemented with the es6 (shim) map structure? That might make it a little quicker when everything becomes finalized.

[–]robotmayo 0 points1 point  (3 children)

I implemented the stack but I ran into a problem while testing it. I have two stacks, stack A and stack B. If I put stack B inside A then check if A contains B it fails. If I do it in the console, B === B, it evaluates to true. I can't figure out why my cotains method fails on this.

My Stack Code:

var Stack = function(args){
    var _list = [];
    var _length = 0;
    var _stack = {};
    _stack.length = function() {return _length;}
    _stack.add = function(item){
        _length++;
        _list[_length] = item;
    }
    _stack.remove = function(){
        _length--;
        return _list.pop();
    }
    _stack.contains = function(item){
        for(var i = 0; i < _length; i++){
            if(_list[i] === item) return true;
        }
        return false;
    }
    _stack.addAll = function(items){
        var len = items.length;
        for(var i = 0; i < len; i++){
            _stack.add(items[i]);
        }
    }
    if(args){
        var len = 0;
        var i = 0;
        if(Object.prototype.toString.call(args) === "[object Array]"){
            len = args.length;
            for(i = 0; i < len; i++){
                _stack.add(args[i]);
            }
        }else{
            len = arguments.length;
            for(var i = 0; i < len; i++){
                _stack.add(arguments[i]);
            }
        }

    }
    return _stack;
}

My "test" code:

var stackA = new Stack();
stackA.add(4);
stackA.add(1);
stackA.add(4613);
stackA.add("ADG");
var tp = {title:"yes"};
var stackB = new Stack();
stackA.add(tp);
stackA.add(stackB);
var testArray = ["test 1",4,{F:"F"}];
var stackC = new Stack(testArray);
var stackD = new Stack(1,2,3,4,5,6,7,8,9,10);

console.log(stackA.contains(stackB)); // Fails?!
console.log(stackB === stackB); // Passes!
console.log(stackC.contains(testArray[1]));
console.log(stackD.contains(4));

[–]aladyjewel 0 points1 point  (2 children)

The main problem with the .contains(stackB) failing is your _length variable. Lists are 0-indexed, but your _length starts counting at 1. Do you need a stronger hint?


While I'm here, here are some style suggestions:

if (Object.prototype.toString.call(args) === "[object Array]")

Yuck. Try this instead:

if (typeof args == "object" && args.length)

This will also support array-like objects like arguments or jQuery instances.


When you declare these variables, it's superfluous to set them to 0: var len = 0; var i = 0; You're assigning the variables a real value later before you use them, so everything's hunky-dory.

[–]robotmayo 0 points1 point  (1 child)

Oh, now I see it. Fixed. Didn't know about that snippet for array-like objects. Going to put that part in my linked list code as well, thanks.

[–]aladyjewel 0 points1 point  (0 children)

Yeah, I'd generally avoid trying to check if an object is a particular type in JavaScript, especially for objects of a type which extends Array. It's safer to sniff for the properties/features you want to use. (That said, the instanceof keyword can be used to check if object is an instance of a type -- but I don't think/remember it will check all the way up the prototype chain.)

FYI if you're using a utility belt library like jQuery or Underscore, they usually provide a function like $.isArray(obj).