DEV Community

Discussion on: Creating 3 Stacks With 1 Array in JavaScript

Collapse
 
patriklarsson profile image
Patrik • Edited

This is a great example and breakdown and nice solution.

It did spawn some thinking though whether it's not feasible to take a more function-oriented approach (with some traditional OOP interspersed) to really hone in on the "a single array" part of the question. By extracting separate objects for the different queues, we can hold positions inside those objects instead, shifting the responsibility completely.

I thought of something like this:

let Arrack = (stacks, maxStackSize, freeStackSlotsWhenDigested=false) => {
    let stackSize = maxStackSize * stacks,
        masterStack = Array(stackSize);

    let QueueHandler = (stack) => {
        if (stack >= stacks) {
            throw "Not enough stacks in this Arrack"
        }

        let stackStart = (stack) * maxStackSize,
            stackPosition = stackStart,
            stackEnd = stackStart + maxStackSize,
            queue = (ob) => {
                if (stackPosition === stackEnd) {
                    throw "Max stack size reached"
                }

                masterStack[stackPosition] = ob;
                stackPosition++;
            },
            digest = () => {
                if (stackPosition === stackStart) {
                    throw "No items to digest"
                }

                stackPosition--;
                let item = masterStack[stackPosition];
                if (freeStackSlotsWhenDigested) {
                    masterStack[stackPosition] = null;
                }
                return item;
            };

        return {
            queue: queue,
            digest: digest
        }

    };

    return {
        initiateStack: QueueHandler
    };
};

We can then initiate an object that holds the values inside it, as well as a handler for each available stack.

The last argument is whether we want to clear the slots once used, or we simply leave out to keep them in-memory (to avoid an additional operation).

let arrack = Arrack(3, 10, true);

Once we have our Arrack we can handle each queue separately.

let stack0 = arrack.initiateStack(0),
    stack1 = arrack.initiateStack(1),
    stack2 = arrack.initiateStack(2);

We then use the queue(ob) and digest() methods to put and get items from our queue.

stack1.queue({
    message: 'foo',
    type: 'bar'
});
stack1.digest();
> {message: "foo", type: "bar"}

I lazily threw errors if we try to digest what we don't have, or put more objects than we're allowed (Python habit I'm afraid), but that could be tweaked.

for (let i=0; i<11; i++) {
    stack2.queue(i);
}
>! Uncaught Max stack size reached

Feedback is very welcome :)