Circular buffer in JavaScript










36















Has anyone already implemented a circular buffer in JavaScript? How would you do that without having pointers?










share|improve this question



















  • 1





    You probably should clarify "circular buffer". What sort of API interests you? What goes in the buffer? etc etc

    – Pointy
    Oct 17 '09 at 20:33











  • Ideally the API would consist of: push ( key, value ) get ( key ) and when the buffer has reached its maximum size the first saved item is overwritten.

    – user191800
    Oct 17 '09 at 21:32















36















Has anyone already implemented a circular buffer in JavaScript? How would you do that without having pointers?










share|improve this question



















  • 1





    You probably should clarify "circular buffer". What sort of API interests you? What goes in the buffer? etc etc

    – Pointy
    Oct 17 '09 at 20:33











  • Ideally the API would consist of: push ( key, value ) get ( key ) and when the buffer has reached its maximum size the first saved item is overwritten.

    – user191800
    Oct 17 '09 at 21:32













36












36








36


18






Has anyone already implemented a circular buffer in JavaScript? How would you do that without having pointers?










share|improve this question
















Has anyone already implemented a circular buffer in JavaScript? How would you do that without having pointers?







javascript data-structures circular-buffer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 16 '13 at 5:36









icktoofay

103k17199210




103k17199210










asked Oct 17 '09 at 20:29







user191800














  • 1





    You probably should clarify "circular buffer". What sort of API interests you? What goes in the buffer? etc etc

    – Pointy
    Oct 17 '09 at 20:33











  • Ideally the API would consist of: push ( key, value ) get ( key ) and when the buffer has reached its maximum size the first saved item is overwritten.

    – user191800
    Oct 17 '09 at 21:32












  • 1





    You probably should clarify "circular buffer". What sort of API interests you? What goes in the buffer? etc etc

    – Pointy
    Oct 17 '09 at 20:33











  • Ideally the API would consist of: push ( key, value ) get ( key ) and when the buffer has reached its maximum size the first saved item is overwritten.

    – user191800
    Oct 17 '09 at 21:32







1




1





You probably should clarify "circular buffer". What sort of API interests you? What goes in the buffer? etc etc

– Pointy
Oct 17 '09 at 20:33





You probably should clarify "circular buffer". What sort of API interests you? What goes in the buffer? etc etc

– Pointy
Oct 17 '09 at 20:33













Ideally the API would consist of: push ( key, value ) get ( key ) and when the buffer has reached its maximum size the first saved item is overwritten.

– user191800
Oct 17 '09 at 21:32





Ideally the API would consist of: push ( key, value ) get ( key ) and when the buffer has reached its maximum size the first saved item is overwritten.

– user191800
Oct 17 '09 at 21:32












14 Answers
14






active

oldest

votes


















30














Strange co-incidence, I just wrote one earlier today! I don't know what exactly your requirements are but this might be of use.



It presents an interface like an Array of unlimited length, but ‘forgets’ old items:



// Circular buffer storage. Externally-apparent 'length' increases indefinitely
// while any items with indexes below length-n will be forgotten (undefined
// will be returned if you try to get them, trying to set is an exception).
// n represents the initial length of the array, not a maximum
function CircularBuffer(n)
this._array= new Array(n);
this.length= 0;

CircularBuffer.prototype.toString= function()
return '[object CircularBuffer('+this._array.length+') length '+this.length+']';
;
CircularBuffer.prototype.get= function(i)
if (i<0 ;
CircularBuffer.prototype.set= function(i, v)
if (i<0 ;
CircularBuffer.IndexError= ;





share|improve this answer




















  • 1





    Nice. I added push: CircularBuffer.prototype.push = function(v) this._array[this.length%this._array.length] = v; this.length++; ;

    – forresto
    Oct 2 '13 at 13:46







  • 2





    "Indefinetely" as in 1.7976931348623157e+308, which in turn exceeding means somewhen Infinity. +1

    – loveNoHate
    Sep 8 '14 at 10:41


















19














var createRingBuffer = function(length)

var pointer = 0, buffer = ;

return
get : function(key)return buffer[key];,
push : function(item)
buffer[pointer] = item;
pointer = (length + pointer +1) % length;

;
;


Update: in case you fill the buffer with numbers only, here are some one liner plugins:



min : function()return Math.min.apply(Math, buffer);,
sum : function()return buffer.reduce(function(a, b) return a + b; , 0);,





share|improve this answer




















  • 3





    why do you have pointer = (length + pointer +1) % length instead of just pointer = (pointer + 1) % length?

    – Muxa
    May 14 '13 at 3:19











  • Change get function to get : function(key) if (key < 0) return buffer[pointer+key]; else if (key === false) return buffer[pointer - 1]; else return buffer[key]; , to support negative indexing (from right) and default to last thing pushed if no key is given.

    – Two-Bit Alchemist
    Jan 20 '15 at 5:18











  • Actually I ended up adding a couple other niceties to this so I submitted a variant answer.

    – Two-Bit Alchemist
    Jan 20 '15 at 5:48


















6














Like many others, I liked noiv's solution, but I wanted a somewhat nicer API:



var createRingBuffer = function(length)
/* https://stackoverflow.com/a/4774081 */
var pointer = 0, buffer = ;

return
get : function(key)
if (key < 0)
return buffer[pointer+key];
else if (key === false)
return buffer[pointer - 1];
else
return buffer[key];

,
push : function(item)
buffer[pointer] = item;
pointer = (pointer + 1) % length;
return item;
,
prev : function()
var tmp_pointer = (pointer - 1) % length;
if (buffer[tmp_pointer])
pointer = tmp_pointer;
return buffer[pointer];

,
next : function()
if (buffer[pointer])
pointer = (pointer + 1) % length;
return buffer[pointer];


;
;


Improvements over original:




  • get supports default argument (returns last item pushed onto buffer)


  • get supports negative indexing (counts from right)


  • prev moves buffer back one and returns what's there (like popping without delete)


  • next undoes prev (moves buffer forward and returns it)

I used this to store a command history which I could then flip through in an app using its prev and next methods, which nicely return undefined when they have nowhere to go.






share|improve this answer
































    4














    This is a quick mockup of the code you could use (it probably isn't working and has bugs in it, but it shows the way it could be done):



    var CircularQueueItem = function(value, next, back) 
    this.next = next;
    this.value = value;
    this.back = back;
    return this;
    ;

    var CircularQueue = function(queueLength)
    /// <summary>Creates a circular queue of specified length</summary>
    /// <param name="queueLength" type="int">Length of the circular queue</type>
    this._current = new CircularQueueItem(undefined, undefined, undefined);
    var item = this._current;
    for(var i = 0; i < queueLength - 1; i++)

    item.next = new CircularQueueItem(undefined, undefined, item);
    item = item.next;

    item.next = this._current;
    this._current.back = item;


    CircularQueue.prototype.push = function(value)
    /// <summary>Pushes a value/object into the circular queue</summary>
    /// <param name="value">Any value/object that should be stored into the queue</param>
    this._current.value = value;
    this._current = this._current.next;
    ;

    CircularQueue.prototype.pop = function()
    /// <summary>Gets the last pushed value/object from the circular queue</summary>
    /// <returns>Returns the last pushed value/object from the circular queue</returns>
    this._current = this._current.back;
    return this._current.value;
    ;


    using this object would be like:



    var queue = new CircularQueue(10); // a circular queue with 10 items
    queue.push(10);
    queue.push(20);
    alert(queue.pop());
    alert(queue.pop());


    You could of course implement it using array as well with a class that would internally use an array and keep a value of the current item index and moving that one.






    share|improve this answer




















    • 2





      What's with all those .NET-style doc comments?

      – Ionuț G. Stan
      Oct 17 '09 at 21:25











    • @Ionut: They're Javascript intellisense for Visual Studio 2008+ just in case he's on .net otherwise they'll simply be ignored by other editors.

      – Robert Koritnik
      Oct 17 '09 at 21:52






    • 1





      I had no idea there's support for them in Visual Studio. Thanks for the info.

      – Ionuț G. Stan
      Oct 17 '09 at 22:31











    • @Ionut: Make sure to write the AFTER function declaration and not BEFORE as normal in C#. That's the main difference. Otherwise it works quite similar.

      – Robert Koritnik
      Oct 18 '09 at 8:22






    • 2





      Unnecessary XML style markup makes me sad but a big thumbs up for structured documentation

      – Steven Lu
      Oct 6 '13 at 0:30


















    3














    I use personally the implementation of Trevor Norris that you can find here:
    https://github.com/trevnorris/cbuffer



    and I'm quite happy with it :-)






    share|improve this answer






























      2














      Short and sweet:



      // IMPLEMENTATION
      function CircularArray(maxLength)
      this.maxLength = maxLength;


      CircularArray.prototype = Object.create(Array.prototype);

      CircularArray.prototype.push = function(element)
      Array.prototype.push.call(this, element);
      while (this.length > this.maxLength)
      this.shift();



      // USAGE
      var ca = new CircularArray(2);
      var i;

      for (i = 0; i < 100; i++)
      ca.push(i);


      console.log(ca[0]);
      console.log(ca[1]);
      console.log("Length: " + ca.length);


      Output:



      98
      99
      Length: 2





      share|improve this answer






























        1














        I couldn't get Robert Koritnik's code to work, so I edited it to the following which seems to work:



         var CircularQueueItem = function (value, next, back) 
        this.next = next;
        this.value = value;
        this.back = back;
        return this;
        ;

        var CircularQueue = function (queueLength)
        /// <summary>Creates a circular queue of specified length</summary>
        /// <param name="queueLength" type="int">Length of the circular queue</type>
        this._current = new CircularQueueItem(undefined, undefined, undefined);
        var item = this._current;
        for (var i = 0; i < queueLength - 1; i++)
        item.next = new CircularQueueItem(undefined, undefined, item);
        item = item.next;

        item.next = this._current;
        this._current.back = item;

        this.push = function (value)
        /// <summary>Pushes a value/object into the circular queue</summary>
        /// <param name="value">Any value/object that should be stored into the queue</param>
        this._current.value = value;
        this._current = this._current.next;
        ;
        this.pop = function ()
        /// <summary>Gets the last pushed value/object from the circular queue</summary>
        /// <returns>Returns the last pushed value/object from the circular queue</returns>
        this._current = this._current.back;
        return this._current.value;
        ;
        return this;



        To use:



         var queue = new CircularQueue(3); // a circular queue with 3 items
        queue.push("a");
        queue.push("b");
        queue.push("c");
        queue.push("d");
        alert(queue.pop()); // d
        alert(queue.pop()); // c
        alert(queue.pop()); // b
        alert(queue.pop()); // d
        alert(queue.pop()); // c





        share|improve this answer























        • Because it's a queue and not a stack, should pop() return the first added element instead of the last one? Am I missing something here? For example imagine we have Mike, Lauren and a ticketing booth queue. Mike joins to the end of the queue. After Mike Lauren joins in. Because the queue, Mike will be served first.

          – Akseli Palén
          Feb 16 '13 at 21:36


















        1














        I really like how noiv11 solved this and for my need I added an extra property 'buffer' which returns the buffer:



        var createRingBuffer = function(length)

        var pointer = 0, buffer = ;

        return
        get : function(key)return buffer[key];,
        push : function(item)
        buffer[pointer] = item;
        pointer = (length + pointer +1) % length;
        ,
        buffer : buffer
        ;
        ;

        // sample use
        var rbuffer = createRingBuffer(3);
        rbuffer.push('a');
        rbuffer.push('b');
        rbuffer.push('c');
        alert(rbuffer.buffer.toString());
        rbuffer.push('d');
        alert(rbuffer.buffer.toString());
        var el = rbuffer.get(0);
        alert(el);





        share|improve this answer

























        • What a horrible thing to do! The buffer was nicely hidden in the original.

          – James
          Jul 24 '14 at 18:42






        • 2





          Agree, no idea why I did it (2 years ago)

          – soderlind
          Jul 31 '14 at 20:38


















        1














        Instead of implementing circular queue with JavaScript, we can use some inbuilt functions of array to achieve circular queue implementation.



        example:
        Suppose we need to implement the circular queue for length 4.



        var circular = new Array();
        var maxLength = 4;
        var addElementToQueue = function(element)
        if(circular.length == maxLength)
        circular.pop();

        circular.unshift(element);
        ;
        addElementToQueue(1);
        addElementToQueue(2);
        addElementToQueue(3);
        addElementToQueue(4);


        Output:



        circular
        [4, 3, 2, 1]



        If you try to add another element to this array eg:



        addElementToQueue(5);


        Output:



        circular
        [5, 4, 3, 2]






        share|improve this answer






























          0














          One approach would be to use a linked list as others have suggested. Another technique would be to use a simple array as the buffer and to keep track of the read and write positions via indices into that array.






          share|improve this answer






























            0














            I think you should be able to do this by just using objects. Something like this:



            var link = function(next, value) 
            this.next = next;
            this.value = value;
            ;

            var last = new link();
            var second = link(last);
            var first = link(second);
            last.next = first;


            Now you'd just store the value in each link's value property.






            share|improve this answer




















            • 1





              I believe you forgot to use the new operator.

              – Ionuț G. Stan
              Oct 17 '09 at 21:31











            • Yep, been coding too much Python as of late =)

              – Jani Hartikainen
              Oct 17 '09 at 23:28











            • lol linked lists your code appears C++

              – ShrekOverflow
              Feb 10 '12 at 18:14


















            0














            Thanks noiv for your simple and efficient solution. I also needed to be able to access the buffer like PerS did, but i wanted to get the items in the order they were added. So here's what i ended up with:



            function buffer(capacity) 
            if (!(capacity > 0))
            throw new Error();


            var pointer = 0, buffer = ;

            var publicObj =
            get: function (key)
            if (key === undefined) buffer.length < capacity)
            // the buffer as it is now is in order
            return buffer;

            // split and join the two parts so the result is in order
            return buffer.slice(pointer).concat(buffer.slice(0, pointer));

            return buffer[key];
            ,
            push: function (item)
            buffer[pointer] = item;
            pointer = (capacity + pointer + 1) % capacity;
            // update public length field
            publicObj.length = buffer.length;
            ,
            capacity: capacity,
            length: 0
            ;

            return publicObj;



            Here is the test suite:



            QUnit.module("buffer");

            QUnit.test("constructor", function ()
            QUnit.expect(4);

            QUnit.equal(buffer(1).capacity, 1, "minimum length of 1 is allowed");
            QUnit.equal(buffer(10).capacity, 10);

            QUnit.throws(
            function ()
            buffer(-1);
            ,
            Error,
            "must throuw exception on negative length"
            );

            QUnit.throws(
            function ()
            buffer(0);
            ,
            Error,
            "must throw exception on zero length"
            );
            );

            QUnit.test("push", function ()
            QUnit.expect(5);

            var b = buffer(5);
            QUnit.equal(b.length, 0);
            b.push("1");
            QUnit.equal(b.length, 1);
            b.push("2");
            b.push("3");
            b.push("4");
            b.push("5");
            QUnit.equal(b.length, 5);
            b.push("6");
            QUnit.equal(b.length, 5);
            b.push("7");
            b.push("8");
            QUnit.equal(b.length, 5);
            );

            QUnit.test("get(key)", function ()
            QUnit.expect(8);

            var b = buffer(3);
            QUnit.equal(b.get(0), undefined);
            b.push("a");
            QUnit.equal(b.get(0), "a");
            b.push("b");
            QUnit.equal(b.get(1), "b");
            b.push("c");
            QUnit.equal(b.get(2), "c");
            b.push("d");
            QUnit.equal(b.get(0), "d");

            b = buffer(1);
            b.push("1");
            QUnit.equal(b.get(0), "1");
            b.push("2");
            QUnit.equal(b.get(0), "2");
            QUnit.equal(b.length, 1);
            );

            QUnit.test("get()", function ()
            QUnit.expect(7);

            var b = buffer(3);
            QUnit.deepEqual(b.get(), );
            b.push("a");
            QUnit.deepEqual(b.get(), ["a"]);
            b.push("b");
            QUnit.deepEqual(b.get(), ["a", "b"]);
            b.push("c");
            QUnit.deepEqual(b.get(), ["a", "b", "c"]);
            b.push("d");
            QUnit.deepEqual(b.get(), ["b", "c", "d"]);
            b.push("e");
            QUnit.deepEqual(b.get(), ["c", "d", "e"]);
            b.push("f");
            QUnit.deepEqual(b.get(), ["d", "e", "f"]);
            );





            share|improve this answer
































              0














              Shameless self plug:



              If you are looking for a rotating node.js buffer, I wrote one that can be found here: http://npmjs.org/packages/pivot-buffer



              Documentation is currently lacking, but RotatingBuffer#push allows you to append a buffer to the current buffer, rotating the previous data if new length is greater than the length specified in the constructor.






              share|improve this answer






























                0














                Its very easy if you now what Array.prototype.length is:



                function CircularBuffer(size) 
                Array.call(this,size); //superclass
                this.length = 0; //current index
                this.size = size; //buffer size
                ;

                CircularBuffer.prototype = Object.create(Array.prototype);
                CircularBuffer.prototype.constructor = CircularBuffer;
                CircularBuffer.prototype.constructor.name = "CircularBuffer";

                CircularBuffer.prototype.push = function push(elem)
                Array.prototype.push.call(this,elem);
                if (this.length >= this.size) this.length = 0;
                return this.length;


                CircularBuffer.prototype.pop = function pop()
                var r = this[this.length];
                if (this.length <= 0) this.length = this.size;
                this.length--;
                return r;






                share|improve this answer
























                  Your Answer






                  StackExchange.ifUsing("editor", function ()
                  StackExchange.using("externalEditor", function ()
                  StackExchange.using("snippets", function ()
                  StackExchange.snippets.init();
                  );
                  );
                  , "code-snippets");

                  StackExchange.ready(function()
                  var channelOptions =
                  tags: "".split(" "),
                  id: "1"
                  ;
                  initTagRenderer("".split(" "), "".split(" "), channelOptions);

                  StackExchange.using("externalEditor", function()
                  // Have to fire editor after snippets, if snippets enabled
                  if (StackExchange.settings.snippets.snippetsEnabled)
                  StackExchange.using("snippets", function()
                  createEditor();
                  );

                  else
                  createEditor();

                  );

                  function createEditor()
                  StackExchange.prepareEditor(
                  heartbeatType: 'answer',
                  autoActivateHeartbeat: false,
                  convertImagesToLinks: true,
                  noModals: true,
                  showLowRepImageUploadWarning: true,
                  reputationToPostImages: 10,
                  bindNavPrevention: true,
                  postfix: "",
                  imageUploader:
                  brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                  contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                  allowUrls: true
                  ,
                  onDemand: true,
                  discardSelector: ".discard-answer"
                  ,immediatelyShowMarkdownHelp:true
                  );



                  );













                  draft saved

                  draft discarded


















                  StackExchange.ready(
                  function ()
                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1583123%2fcircular-buffer-in-javascript%23new-answer', 'question_page');

                  );

                  Post as a guest















                  Required, but never shown
























                  14 Answers
                  14






                  active

                  oldest

                  votes








                  14 Answers
                  14






                  active

                  oldest

                  votes









                  active

                  oldest

                  votes






                  active

                  oldest

                  votes









                  30














                  Strange co-incidence, I just wrote one earlier today! I don't know what exactly your requirements are but this might be of use.



                  It presents an interface like an Array of unlimited length, but ‘forgets’ old items:



                  // Circular buffer storage. Externally-apparent 'length' increases indefinitely
                  // while any items with indexes below length-n will be forgotten (undefined
                  // will be returned if you try to get them, trying to set is an exception).
                  // n represents the initial length of the array, not a maximum
                  function CircularBuffer(n)
                  this._array= new Array(n);
                  this.length= 0;

                  CircularBuffer.prototype.toString= function()
                  return '[object CircularBuffer('+this._array.length+') length '+this.length+']';
                  ;
                  CircularBuffer.prototype.get= function(i)
                  if (i<0 ;
                  CircularBuffer.prototype.set= function(i, v)
                  if (i<0 ;
                  CircularBuffer.IndexError= ;





                  share|improve this answer




















                  • 1





                    Nice. I added push: CircularBuffer.prototype.push = function(v) this._array[this.length%this._array.length] = v; this.length++; ;

                    – forresto
                    Oct 2 '13 at 13:46







                  • 2





                    "Indefinetely" as in 1.7976931348623157e+308, which in turn exceeding means somewhen Infinity. +1

                    – loveNoHate
                    Sep 8 '14 at 10:41















                  30














                  Strange co-incidence, I just wrote one earlier today! I don't know what exactly your requirements are but this might be of use.



                  It presents an interface like an Array of unlimited length, but ‘forgets’ old items:



                  // Circular buffer storage. Externally-apparent 'length' increases indefinitely
                  // while any items with indexes below length-n will be forgotten (undefined
                  // will be returned if you try to get them, trying to set is an exception).
                  // n represents the initial length of the array, not a maximum
                  function CircularBuffer(n)
                  this._array= new Array(n);
                  this.length= 0;

                  CircularBuffer.prototype.toString= function()
                  return '[object CircularBuffer('+this._array.length+') length '+this.length+']';
                  ;
                  CircularBuffer.prototype.get= function(i)
                  if (i<0 ;
                  CircularBuffer.prototype.set= function(i, v)
                  if (i<0 ;
                  CircularBuffer.IndexError= ;





                  share|improve this answer




















                  • 1





                    Nice. I added push: CircularBuffer.prototype.push = function(v) this._array[this.length%this._array.length] = v; this.length++; ;

                    – forresto
                    Oct 2 '13 at 13:46







                  • 2





                    "Indefinetely" as in 1.7976931348623157e+308, which in turn exceeding means somewhen Infinity. +1

                    – loveNoHate
                    Sep 8 '14 at 10:41













                  30












                  30








                  30







                  Strange co-incidence, I just wrote one earlier today! I don't know what exactly your requirements are but this might be of use.



                  It presents an interface like an Array of unlimited length, but ‘forgets’ old items:



                  // Circular buffer storage. Externally-apparent 'length' increases indefinitely
                  // while any items with indexes below length-n will be forgotten (undefined
                  // will be returned if you try to get them, trying to set is an exception).
                  // n represents the initial length of the array, not a maximum
                  function CircularBuffer(n)
                  this._array= new Array(n);
                  this.length= 0;

                  CircularBuffer.prototype.toString= function()
                  return '[object CircularBuffer('+this._array.length+') length '+this.length+']';
                  ;
                  CircularBuffer.prototype.get= function(i)
                  if (i<0 ;
                  CircularBuffer.prototype.set= function(i, v)
                  if (i<0 ;
                  CircularBuffer.IndexError= ;





                  share|improve this answer















                  Strange co-incidence, I just wrote one earlier today! I don't know what exactly your requirements are but this might be of use.



                  It presents an interface like an Array of unlimited length, but ‘forgets’ old items:



                  // Circular buffer storage. Externally-apparent 'length' increases indefinitely
                  // while any items with indexes below length-n will be forgotten (undefined
                  // will be returned if you try to get them, trying to set is an exception).
                  // n represents the initial length of the array, not a maximum
                  function CircularBuffer(n)
                  this._array= new Array(n);
                  this.length= 0;

                  CircularBuffer.prototype.toString= function()
                  return '[object CircularBuffer('+this._array.length+') length '+this.length+']';
                  ;
                  CircularBuffer.prototype.get= function(i)
                  if (i<0 ;
                  CircularBuffer.prototype.set= function(i, v)
                  if (i<0 ;
                  CircularBuffer.IndexError= ;






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jul 2 '11 at 22:27









                  amirpc

                  80521322




                  80521322










                  answered Oct 17 '09 at 21:31









                  bobincebobince

                  444k89571770




                  444k89571770







                  • 1





                    Nice. I added push: CircularBuffer.prototype.push = function(v) this._array[this.length%this._array.length] = v; this.length++; ;

                    – forresto
                    Oct 2 '13 at 13:46







                  • 2





                    "Indefinetely" as in 1.7976931348623157e+308, which in turn exceeding means somewhen Infinity. +1

                    – loveNoHate
                    Sep 8 '14 at 10:41












                  • 1





                    Nice. I added push: CircularBuffer.prototype.push = function(v) this._array[this.length%this._array.length] = v; this.length++; ;

                    – forresto
                    Oct 2 '13 at 13:46







                  • 2





                    "Indefinetely" as in 1.7976931348623157e+308, which in turn exceeding means somewhen Infinity. +1

                    – loveNoHate
                    Sep 8 '14 at 10:41







                  1




                  1





                  Nice. I added push: CircularBuffer.prototype.push = function(v) this._array[this.length%this._array.length] = v; this.length++; ;

                  – forresto
                  Oct 2 '13 at 13:46






                  Nice. I added push: CircularBuffer.prototype.push = function(v) this._array[this.length%this._array.length] = v; this.length++; ;

                  – forresto
                  Oct 2 '13 at 13:46





                  2




                  2





                  "Indefinetely" as in 1.7976931348623157e+308, which in turn exceeding means somewhen Infinity. +1

                  – loveNoHate
                  Sep 8 '14 at 10:41





                  "Indefinetely" as in 1.7976931348623157e+308, which in turn exceeding means somewhen Infinity. +1

                  – loveNoHate
                  Sep 8 '14 at 10:41













                  19














                  var createRingBuffer = function(length)

                  var pointer = 0, buffer = ;

                  return
                  get : function(key)return buffer[key];,
                  push : function(item)
                  buffer[pointer] = item;
                  pointer = (length + pointer +1) % length;

                  ;
                  ;


                  Update: in case you fill the buffer with numbers only, here are some one liner plugins:



                  min : function()return Math.min.apply(Math, buffer);,
                  sum : function()return buffer.reduce(function(a, b) return a + b; , 0);,





                  share|improve this answer




















                  • 3





                    why do you have pointer = (length + pointer +1) % length instead of just pointer = (pointer + 1) % length?

                    – Muxa
                    May 14 '13 at 3:19











                  • Change get function to get : function(key) if (key < 0) return buffer[pointer+key]; else if (key === false) return buffer[pointer - 1]; else return buffer[key]; , to support negative indexing (from right) and default to last thing pushed if no key is given.

                    – Two-Bit Alchemist
                    Jan 20 '15 at 5:18











                  • Actually I ended up adding a couple other niceties to this so I submitted a variant answer.

                    – Two-Bit Alchemist
                    Jan 20 '15 at 5:48















                  19














                  var createRingBuffer = function(length)

                  var pointer = 0, buffer = ;

                  return
                  get : function(key)return buffer[key];,
                  push : function(item)
                  buffer[pointer] = item;
                  pointer = (length + pointer +1) % length;

                  ;
                  ;


                  Update: in case you fill the buffer with numbers only, here are some one liner plugins:



                  min : function()return Math.min.apply(Math, buffer);,
                  sum : function()return buffer.reduce(function(a, b) return a + b; , 0);,





                  share|improve this answer




















                  • 3





                    why do you have pointer = (length + pointer +1) % length instead of just pointer = (pointer + 1) % length?

                    – Muxa
                    May 14 '13 at 3:19











                  • Change get function to get : function(key) if (key < 0) return buffer[pointer+key]; else if (key === false) return buffer[pointer - 1]; else return buffer[key]; , to support negative indexing (from right) and default to last thing pushed if no key is given.

                    – Two-Bit Alchemist
                    Jan 20 '15 at 5:18











                  • Actually I ended up adding a couple other niceties to this so I submitted a variant answer.

                    – Two-Bit Alchemist
                    Jan 20 '15 at 5:48













                  19












                  19








                  19







                  var createRingBuffer = function(length)

                  var pointer = 0, buffer = ;

                  return
                  get : function(key)return buffer[key];,
                  push : function(item)
                  buffer[pointer] = item;
                  pointer = (length + pointer +1) % length;

                  ;
                  ;


                  Update: in case you fill the buffer with numbers only, here are some one liner plugins:



                  min : function()return Math.min.apply(Math, buffer);,
                  sum : function()return buffer.reduce(function(a, b) return a + b; , 0);,





                  share|improve this answer















                  var createRingBuffer = function(length)

                  var pointer = 0, buffer = ;

                  return
                  get : function(key)return buffer[key];,
                  push : function(item)
                  buffer[pointer] = item;
                  pointer = (length + pointer +1) % length;

                  ;
                  ;


                  Update: in case you fill the buffer with numbers only, here are some one liner plugins:



                  min : function()return Math.min.apply(Math, buffer);,
                  sum : function()return buffer.reduce(function(a, b) return a + b; , 0);,






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Oct 19 '12 at 11:05

























                  answered Jan 23 '11 at 13:30









                  Torsten BeckerTorsten Becker

                  3,82021619




                  3,82021619







                  • 3





                    why do you have pointer = (length + pointer +1) % length instead of just pointer = (pointer + 1) % length?

                    – Muxa
                    May 14 '13 at 3:19











                  • Change get function to get : function(key) if (key < 0) return buffer[pointer+key]; else if (key === false) return buffer[pointer - 1]; else return buffer[key]; , to support negative indexing (from right) and default to last thing pushed if no key is given.

                    – Two-Bit Alchemist
                    Jan 20 '15 at 5:18











                  • Actually I ended up adding a couple other niceties to this so I submitted a variant answer.

                    – Two-Bit Alchemist
                    Jan 20 '15 at 5:48












                  • 3





                    why do you have pointer = (length + pointer +1) % length instead of just pointer = (pointer + 1) % length?

                    – Muxa
                    May 14 '13 at 3:19











                  • Change get function to get : function(key) if (key < 0) return buffer[pointer+key]; else if (key === false) return buffer[pointer - 1]; else return buffer[key]; , to support negative indexing (from right) and default to last thing pushed if no key is given.

                    – Two-Bit Alchemist
                    Jan 20 '15 at 5:18











                  • Actually I ended up adding a couple other niceties to this so I submitted a variant answer.

                    – Two-Bit Alchemist
                    Jan 20 '15 at 5:48







                  3




                  3





                  why do you have pointer = (length + pointer +1) % length instead of just pointer = (pointer + 1) % length?

                  – Muxa
                  May 14 '13 at 3:19





                  why do you have pointer = (length + pointer +1) % length instead of just pointer = (pointer + 1) % length?

                  – Muxa
                  May 14 '13 at 3:19













                  Change get function to get : function(key) if (key < 0) return buffer[pointer+key]; else if (key === false) return buffer[pointer - 1]; else return buffer[key]; , to support negative indexing (from right) and default to last thing pushed if no key is given.

                  – Two-Bit Alchemist
                  Jan 20 '15 at 5:18





                  Change get function to get : function(key) if (key < 0) return buffer[pointer+key]; else if (key === false) return buffer[pointer - 1]; else return buffer[key]; , to support negative indexing (from right) and default to last thing pushed if no key is given.

                  – Two-Bit Alchemist
                  Jan 20 '15 at 5:18













                  Actually I ended up adding a couple other niceties to this so I submitted a variant answer.

                  – Two-Bit Alchemist
                  Jan 20 '15 at 5:48





                  Actually I ended up adding a couple other niceties to this so I submitted a variant answer.

                  – Two-Bit Alchemist
                  Jan 20 '15 at 5:48











                  6














                  Like many others, I liked noiv's solution, but I wanted a somewhat nicer API:



                  var createRingBuffer = function(length)
                  /* https://stackoverflow.com/a/4774081 */
                  var pointer = 0, buffer = ;

                  return
                  get : function(key)
                  if (key < 0)
                  return buffer[pointer+key];
                  else if (key === false)
                  return buffer[pointer - 1];
                  else
                  return buffer[key];

                  ,
                  push : function(item)
                  buffer[pointer] = item;
                  pointer = (pointer + 1) % length;
                  return item;
                  ,
                  prev : function()
                  var tmp_pointer = (pointer - 1) % length;
                  if (buffer[tmp_pointer])
                  pointer = tmp_pointer;
                  return buffer[pointer];

                  ,
                  next : function()
                  if (buffer[pointer])
                  pointer = (pointer + 1) % length;
                  return buffer[pointer];


                  ;
                  ;


                  Improvements over original:




                  • get supports default argument (returns last item pushed onto buffer)


                  • get supports negative indexing (counts from right)


                  • prev moves buffer back one and returns what's there (like popping without delete)


                  • next undoes prev (moves buffer forward and returns it)

                  I used this to store a command history which I could then flip through in an app using its prev and next methods, which nicely return undefined when they have nowhere to go.






                  share|improve this answer





























                    6














                    Like many others, I liked noiv's solution, but I wanted a somewhat nicer API:



                    var createRingBuffer = function(length)
                    /* https://stackoverflow.com/a/4774081 */
                    var pointer = 0, buffer = ;

                    return
                    get : function(key)
                    if (key < 0)
                    return buffer[pointer+key];
                    else if (key === false)
                    return buffer[pointer - 1];
                    else
                    return buffer[key];

                    ,
                    push : function(item)
                    buffer[pointer] = item;
                    pointer = (pointer + 1) % length;
                    return item;
                    ,
                    prev : function()
                    var tmp_pointer = (pointer - 1) % length;
                    if (buffer[tmp_pointer])
                    pointer = tmp_pointer;
                    return buffer[pointer];

                    ,
                    next : function()
                    if (buffer[pointer])
                    pointer = (pointer + 1) % length;
                    return buffer[pointer];


                    ;
                    ;


                    Improvements over original:




                    • get supports default argument (returns last item pushed onto buffer)


                    • get supports negative indexing (counts from right)


                    • prev moves buffer back one and returns what's there (like popping without delete)


                    • next undoes prev (moves buffer forward and returns it)

                    I used this to store a command history which I could then flip through in an app using its prev and next methods, which nicely return undefined when they have nowhere to go.






                    share|improve this answer



























                      6












                      6








                      6







                      Like many others, I liked noiv's solution, but I wanted a somewhat nicer API:



                      var createRingBuffer = function(length)
                      /* https://stackoverflow.com/a/4774081 */
                      var pointer = 0, buffer = ;

                      return
                      get : function(key)
                      if (key < 0)
                      return buffer[pointer+key];
                      else if (key === false)
                      return buffer[pointer - 1];
                      else
                      return buffer[key];

                      ,
                      push : function(item)
                      buffer[pointer] = item;
                      pointer = (pointer + 1) % length;
                      return item;
                      ,
                      prev : function()
                      var tmp_pointer = (pointer - 1) % length;
                      if (buffer[tmp_pointer])
                      pointer = tmp_pointer;
                      return buffer[pointer];

                      ,
                      next : function()
                      if (buffer[pointer])
                      pointer = (pointer + 1) % length;
                      return buffer[pointer];


                      ;
                      ;


                      Improvements over original:




                      • get supports default argument (returns last item pushed onto buffer)


                      • get supports negative indexing (counts from right)


                      • prev moves buffer back one and returns what's there (like popping without delete)


                      • next undoes prev (moves buffer forward and returns it)

                      I used this to store a command history which I could then flip through in an app using its prev and next methods, which nicely return undefined when they have nowhere to go.






                      share|improve this answer















                      Like many others, I liked noiv's solution, but I wanted a somewhat nicer API:



                      var createRingBuffer = function(length)
                      /* https://stackoverflow.com/a/4774081 */
                      var pointer = 0, buffer = ;

                      return
                      get : function(key)
                      if (key < 0)
                      return buffer[pointer+key];
                      else if (key === false)
                      return buffer[pointer - 1];
                      else
                      return buffer[key];

                      ,
                      push : function(item)
                      buffer[pointer] = item;
                      pointer = (pointer + 1) % length;
                      return item;
                      ,
                      prev : function()
                      var tmp_pointer = (pointer - 1) % length;
                      if (buffer[tmp_pointer])
                      pointer = tmp_pointer;
                      return buffer[pointer];

                      ,
                      next : function()
                      if (buffer[pointer])
                      pointer = (pointer + 1) % length;
                      return buffer[pointer];


                      ;
                      ;


                      Improvements over original:




                      • get supports default argument (returns last item pushed onto buffer)


                      • get supports negative indexing (counts from right)


                      • prev moves buffer back one and returns what's there (like popping without delete)


                      • next undoes prev (moves buffer forward and returns it)

                      I used this to store a command history which I could then flip through in an app using its prev and next methods, which nicely return undefined when they have nowhere to go.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited May 23 '17 at 11:47









                      Community

                      11




                      11










                      answered Jan 20 '15 at 5:45









                      Two-Bit AlchemistTwo-Bit Alchemist

                      10.6k43063




                      10.6k43063





















                          4














                          This is a quick mockup of the code you could use (it probably isn't working and has bugs in it, but it shows the way it could be done):



                          var CircularQueueItem = function(value, next, back) 
                          this.next = next;
                          this.value = value;
                          this.back = back;
                          return this;
                          ;

                          var CircularQueue = function(queueLength)
                          /// <summary>Creates a circular queue of specified length</summary>
                          /// <param name="queueLength" type="int">Length of the circular queue</type>
                          this._current = new CircularQueueItem(undefined, undefined, undefined);
                          var item = this._current;
                          for(var i = 0; i < queueLength - 1; i++)

                          item.next = new CircularQueueItem(undefined, undefined, item);
                          item = item.next;

                          item.next = this._current;
                          this._current.back = item;


                          CircularQueue.prototype.push = function(value)
                          /// <summary>Pushes a value/object into the circular queue</summary>
                          /// <param name="value">Any value/object that should be stored into the queue</param>
                          this._current.value = value;
                          this._current = this._current.next;
                          ;

                          CircularQueue.prototype.pop = function()
                          /// <summary>Gets the last pushed value/object from the circular queue</summary>
                          /// <returns>Returns the last pushed value/object from the circular queue</returns>
                          this._current = this._current.back;
                          return this._current.value;
                          ;


                          using this object would be like:



                          var queue = new CircularQueue(10); // a circular queue with 10 items
                          queue.push(10);
                          queue.push(20);
                          alert(queue.pop());
                          alert(queue.pop());


                          You could of course implement it using array as well with a class that would internally use an array and keep a value of the current item index and moving that one.






                          share|improve this answer




















                          • 2





                            What's with all those .NET-style doc comments?

                            – Ionuț G. Stan
                            Oct 17 '09 at 21:25











                          • @Ionut: They're Javascript intellisense for Visual Studio 2008+ just in case he's on .net otherwise they'll simply be ignored by other editors.

                            – Robert Koritnik
                            Oct 17 '09 at 21:52






                          • 1





                            I had no idea there's support for them in Visual Studio. Thanks for the info.

                            – Ionuț G. Stan
                            Oct 17 '09 at 22:31











                          • @Ionut: Make sure to write the AFTER function declaration and not BEFORE as normal in C#. That's the main difference. Otherwise it works quite similar.

                            – Robert Koritnik
                            Oct 18 '09 at 8:22






                          • 2





                            Unnecessary XML style markup makes me sad but a big thumbs up for structured documentation

                            – Steven Lu
                            Oct 6 '13 at 0:30















                          4














                          This is a quick mockup of the code you could use (it probably isn't working and has bugs in it, but it shows the way it could be done):



                          var CircularQueueItem = function(value, next, back) 
                          this.next = next;
                          this.value = value;
                          this.back = back;
                          return this;
                          ;

                          var CircularQueue = function(queueLength)
                          /// <summary>Creates a circular queue of specified length</summary>
                          /// <param name="queueLength" type="int">Length of the circular queue</type>
                          this._current = new CircularQueueItem(undefined, undefined, undefined);
                          var item = this._current;
                          for(var i = 0; i < queueLength - 1; i++)

                          item.next = new CircularQueueItem(undefined, undefined, item);
                          item = item.next;

                          item.next = this._current;
                          this._current.back = item;


                          CircularQueue.prototype.push = function(value)
                          /// <summary>Pushes a value/object into the circular queue</summary>
                          /// <param name="value">Any value/object that should be stored into the queue</param>
                          this._current.value = value;
                          this._current = this._current.next;
                          ;

                          CircularQueue.prototype.pop = function()
                          /// <summary>Gets the last pushed value/object from the circular queue</summary>
                          /// <returns>Returns the last pushed value/object from the circular queue</returns>
                          this._current = this._current.back;
                          return this._current.value;
                          ;


                          using this object would be like:



                          var queue = new CircularQueue(10); // a circular queue with 10 items
                          queue.push(10);
                          queue.push(20);
                          alert(queue.pop());
                          alert(queue.pop());


                          You could of course implement it using array as well with a class that would internally use an array and keep a value of the current item index and moving that one.






                          share|improve this answer




















                          • 2





                            What's with all those .NET-style doc comments?

                            – Ionuț G. Stan
                            Oct 17 '09 at 21:25











                          • @Ionut: They're Javascript intellisense for Visual Studio 2008+ just in case he's on .net otherwise they'll simply be ignored by other editors.

                            – Robert Koritnik
                            Oct 17 '09 at 21:52






                          • 1





                            I had no idea there's support for them in Visual Studio. Thanks for the info.

                            – Ionuț G. Stan
                            Oct 17 '09 at 22:31











                          • @Ionut: Make sure to write the AFTER function declaration and not BEFORE as normal in C#. That's the main difference. Otherwise it works quite similar.

                            – Robert Koritnik
                            Oct 18 '09 at 8:22






                          • 2





                            Unnecessary XML style markup makes me sad but a big thumbs up for structured documentation

                            – Steven Lu
                            Oct 6 '13 at 0:30













                          4












                          4








                          4







                          This is a quick mockup of the code you could use (it probably isn't working and has bugs in it, but it shows the way it could be done):



                          var CircularQueueItem = function(value, next, back) 
                          this.next = next;
                          this.value = value;
                          this.back = back;
                          return this;
                          ;

                          var CircularQueue = function(queueLength)
                          /// <summary>Creates a circular queue of specified length</summary>
                          /// <param name="queueLength" type="int">Length of the circular queue</type>
                          this._current = new CircularQueueItem(undefined, undefined, undefined);
                          var item = this._current;
                          for(var i = 0; i < queueLength - 1; i++)

                          item.next = new CircularQueueItem(undefined, undefined, item);
                          item = item.next;

                          item.next = this._current;
                          this._current.back = item;


                          CircularQueue.prototype.push = function(value)
                          /// <summary>Pushes a value/object into the circular queue</summary>
                          /// <param name="value">Any value/object that should be stored into the queue</param>
                          this._current.value = value;
                          this._current = this._current.next;
                          ;

                          CircularQueue.prototype.pop = function()
                          /// <summary>Gets the last pushed value/object from the circular queue</summary>
                          /// <returns>Returns the last pushed value/object from the circular queue</returns>
                          this._current = this._current.back;
                          return this._current.value;
                          ;


                          using this object would be like:



                          var queue = new CircularQueue(10); // a circular queue with 10 items
                          queue.push(10);
                          queue.push(20);
                          alert(queue.pop());
                          alert(queue.pop());


                          You could of course implement it using array as well with a class that would internally use an array and keep a value of the current item index and moving that one.






                          share|improve this answer















                          This is a quick mockup of the code you could use (it probably isn't working and has bugs in it, but it shows the way it could be done):



                          var CircularQueueItem = function(value, next, back) 
                          this.next = next;
                          this.value = value;
                          this.back = back;
                          return this;
                          ;

                          var CircularQueue = function(queueLength)
                          /// <summary>Creates a circular queue of specified length</summary>
                          /// <param name="queueLength" type="int">Length of the circular queue</type>
                          this._current = new CircularQueueItem(undefined, undefined, undefined);
                          var item = this._current;
                          for(var i = 0; i < queueLength - 1; i++)

                          item.next = new CircularQueueItem(undefined, undefined, item);
                          item = item.next;

                          item.next = this._current;
                          this._current.back = item;


                          CircularQueue.prototype.push = function(value)
                          /// <summary>Pushes a value/object into the circular queue</summary>
                          /// <param name="value">Any value/object that should be stored into the queue</param>
                          this._current.value = value;
                          this._current = this._current.next;
                          ;

                          CircularQueue.prototype.pop = function()
                          /// <summary>Gets the last pushed value/object from the circular queue</summary>
                          /// <returns>Returns the last pushed value/object from the circular queue</returns>
                          this._current = this._current.back;
                          return this._current.value;
                          ;


                          using this object would be like:



                          var queue = new CircularQueue(10); // a circular queue with 10 items
                          queue.push(10);
                          queue.push(20);
                          alert(queue.pop());
                          alert(queue.pop());


                          You could of course implement it using array as well with a class that would internally use an array and keep a value of the current item index and moving that one.







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Sep 28 '10 at 8:16

























                          answered Oct 17 '09 at 20:51









                          Robert KoritnikRobert Koritnik

                          77.2k42241365




                          77.2k42241365







                          • 2





                            What's with all those .NET-style doc comments?

                            – Ionuț G. Stan
                            Oct 17 '09 at 21:25











                          • @Ionut: They're Javascript intellisense for Visual Studio 2008+ just in case he's on .net otherwise they'll simply be ignored by other editors.

                            – Robert Koritnik
                            Oct 17 '09 at 21:52






                          • 1





                            I had no idea there's support for them in Visual Studio. Thanks for the info.

                            – Ionuț G. Stan
                            Oct 17 '09 at 22:31











                          • @Ionut: Make sure to write the AFTER function declaration and not BEFORE as normal in C#. That's the main difference. Otherwise it works quite similar.

                            – Robert Koritnik
                            Oct 18 '09 at 8:22






                          • 2





                            Unnecessary XML style markup makes me sad but a big thumbs up for structured documentation

                            – Steven Lu
                            Oct 6 '13 at 0:30












                          • 2





                            What's with all those .NET-style doc comments?

                            – Ionuț G. Stan
                            Oct 17 '09 at 21:25











                          • @Ionut: They're Javascript intellisense for Visual Studio 2008+ just in case he's on .net otherwise they'll simply be ignored by other editors.

                            – Robert Koritnik
                            Oct 17 '09 at 21:52






                          • 1





                            I had no idea there's support for them in Visual Studio. Thanks for the info.

                            – Ionuț G. Stan
                            Oct 17 '09 at 22:31











                          • @Ionut: Make sure to write the AFTER function declaration and not BEFORE as normal in C#. That's the main difference. Otherwise it works quite similar.

                            – Robert Koritnik
                            Oct 18 '09 at 8:22






                          • 2





                            Unnecessary XML style markup makes me sad but a big thumbs up for structured documentation

                            – Steven Lu
                            Oct 6 '13 at 0:30







                          2




                          2





                          What's with all those .NET-style doc comments?

                          – Ionuț G. Stan
                          Oct 17 '09 at 21:25





                          What's with all those .NET-style doc comments?

                          – Ionuț G. Stan
                          Oct 17 '09 at 21:25













                          @Ionut: They're Javascript intellisense for Visual Studio 2008+ just in case he's on .net otherwise they'll simply be ignored by other editors.

                          – Robert Koritnik
                          Oct 17 '09 at 21:52





                          @Ionut: They're Javascript intellisense for Visual Studio 2008+ just in case he's on .net otherwise they'll simply be ignored by other editors.

                          – Robert Koritnik
                          Oct 17 '09 at 21:52




                          1




                          1





                          I had no idea there's support for them in Visual Studio. Thanks for the info.

                          – Ionuț G. Stan
                          Oct 17 '09 at 22:31





                          I had no idea there's support for them in Visual Studio. Thanks for the info.

                          – Ionuț G. Stan
                          Oct 17 '09 at 22:31













                          @Ionut: Make sure to write the AFTER function declaration and not BEFORE as normal in C#. That's the main difference. Otherwise it works quite similar.

                          – Robert Koritnik
                          Oct 18 '09 at 8:22





                          @Ionut: Make sure to write the AFTER function declaration and not BEFORE as normal in C#. That's the main difference. Otherwise it works quite similar.

                          – Robert Koritnik
                          Oct 18 '09 at 8:22




                          2




                          2





                          Unnecessary XML style markup makes me sad but a big thumbs up for structured documentation

                          – Steven Lu
                          Oct 6 '13 at 0:30





                          Unnecessary XML style markup makes me sad but a big thumbs up for structured documentation

                          – Steven Lu
                          Oct 6 '13 at 0:30











                          3














                          I use personally the implementation of Trevor Norris that you can find here:
                          https://github.com/trevnorris/cbuffer



                          and I'm quite happy with it :-)






                          share|improve this answer



























                            3














                            I use personally the implementation of Trevor Norris that you can find here:
                            https://github.com/trevnorris/cbuffer



                            and I'm quite happy with it :-)






                            share|improve this answer

























                              3












                              3








                              3







                              I use personally the implementation of Trevor Norris that you can find here:
                              https://github.com/trevnorris/cbuffer



                              and I'm quite happy with it :-)






                              share|improve this answer













                              I use personally the implementation of Trevor Norris that you can find here:
                              https://github.com/trevnorris/cbuffer



                              and I'm quite happy with it :-)







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered May 18 '14 at 9:45









                              laurentIsRunninglaurentIsRunning

                              888




                              888





















                                  2














                                  Short and sweet:



                                  // IMPLEMENTATION
                                  function CircularArray(maxLength)
                                  this.maxLength = maxLength;


                                  CircularArray.prototype = Object.create(Array.prototype);

                                  CircularArray.prototype.push = function(element)
                                  Array.prototype.push.call(this, element);
                                  while (this.length > this.maxLength)
                                  this.shift();



                                  // USAGE
                                  var ca = new CircularArray(2);
                                  var i;

                                  for (i = 0; i < 100; i++)
                                  ca.push(i);


                                  console.log(ca[0]);
                                  console.log(ca[1]);
                                  console.log("Length: " + ca.length);


                                  Output:



                                  98
                                  99
                                  Length: 2





                                  share|improve this answer



























                                    2














                                    Short and sweet:



                                    // IMPLEMENTATION
                                    function CircularArray(maxLength)
                                    this.maxLength = maxLength;


                                    CircularArray.prototype = Object.create(Array.prototype);

                                    CircularArray.prototype.push = function(element)
                                    Array.prototype.push.call(this, element);
                                    while (this.length > this.maxLength)
                                    this.shift();



                                    // USAGE
                                    var ca = new CircularArray(2);
                                    var i;

                                    for (i = 0; i < 100; i++)
                                    ca.push(i);


                                    console.log(ca[0]);
                                    console.log(ca[1]);
                                    console.log("Length: " + ca.length);


                                    Output:



                                    98
                                    99
                                    Length: 2





                                    share|improve this answer

























                                      2












                                      2








                                      2







                                      Short and sweet:



                                      // IMPLEMENTATION
                                      function CircularArray(maxLength)
                                      this.maxLength = maxLength;


                                      CircularArray.prototype = Object.create(Array.prototype);

                                      CircularArray.prototype.push = function(element)
                                      Array.prototype.push.call(this, element);
                                      while (this.length > this.maxLength)
                                      this.shift();



                                      // USAGE
                                      var ca = new CircularArray(2);
                                      var i;

                                      for (i = 0; i < 100; i++)
                                      ca.push(i);


                                      console.log(ca[0]);
                                      console.log(ca[1]);
                                      console.log("Length: " + ca.length);


                                      Output:



                                      98
                                      99
                                      Length: 2





                                      share|improve this answer













                                      Short and sweet:



                                      // IMPLEMENTATION
                                      function CircularArray(maxLength)
                                      this.maxLength = maxLength;


                                      CircularArray.prototype = Object.create(Array.prototype);

                                      CircularArray.prototype.push = function(element)
                                      Array.prototype.push.call(this, element);
                                      while (this.length > this.maxLength)
                                      this.shift();



                                      // USAGE
                                      var ca = new CircularArray(2);
                                      var i;

                                      for (i = 0; i < 100; i++)
                                      ca.push(i);


                                      console.log(ca[0]);
                                      console.log(ca[1]);
                                      console.log("Length: " + ca.length);


                                      Output:



                                      98
                                      99
                                      Length: 2






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Apr 2 '15 at 15:29









                                      Oliver HeardOliver Heard

                                      211




                                      211





















                                          1














                                          I couldn't get Robert Koritnik's code to work, so I edited it to the following which seems to work:



                                           var CircularQueueItem = function (value, next, back) 
                                          this.next = next;
                                          this.value = value;
                                          this.back = back;
                                          return this;
                                          ;

                                          var CircularQueue = function (queueLength)
                                          /// <summary>Creates a circular queue of specified length</summary>
                                          /// <param name="queueLength" type="int">Length of the circular queue</type>
                                          this._current = new CircularQueueItem(undefined, undefined, undefined);
                                          var item = this._current;
                                          for (var i = 0; i < queueLength - 1; i++)
                                          item.next = new CircularQueueItem(undefined, undefined, item);
                                          item = item.next;

                                          item.next = this._current;
                                          this._current.back = item;

                                          this.push = function (value)
                                          /// <summary>Pushes a value/object into the circular queue</summary>
                                          /// <param name="value">Any value/object that should be stored into the queue</param>
                                          this._current.value = value;
                                          this._current = this._current.next;
                                          ;
                                          this.pop = function ()
                                          /// <summary>Gets the last pushed value/object from the circular queue</summary>
                                          /// <returns>Returns the last pushed value/object from the circular queue</returns>
                                          this._current = this._current.back;
                                          return this._current.value;
                                          ;
                                          return this;



                                          To use:



                                           var queue = new CircularQueue(3); // a circular queue with 3 items
                                          queue.push("a");
                                          queue.push("b");
                                          queue.push("c");
                                          queue.push("d");
                                          alert(queue.pop()); // d
                                          alert(queue.pop()); // c
                                          alert(queue.pop()); // b
                                          alert(queue.pop()); // d
                                          alert(queue.pop()); // c





                                          share|improve this answer























                                          • Because it's a queue and not a stack, should pop() return the first added element instead of the last one? Am I missing something here? For example imagine we have Mike, Lauren and a ticketing booth queue. Mike joins to the end of the queue. After Mike Lauren joins in. Because the queue, Mike will be served first.

                                            – Akseli Palén
                                            Feb 16 '13 at 21:36















                                          1














                                          I couldn't get Robert Koritnik's code to work, so I edited it to the following which seems to work:



                                           var CircularQueueItem = function (value, next, back) 
                                          this.next = next;
                                          this.value = value;
                                          this.back = back;
                                          return this;
                                          ;

                                          var CircularQueue = function (queueLength)
                                          /// <summary>Creates a circular queue of specified length</summary>
                                          /// <param name="queueLength" type="int">Length of the circular queue</type>
                                          this._current = new CircularQueueItem(undefined, undefined, undefined);
                                          var item = this._current;
                                          for (var i = 0; i < queueLength - 1; i++)
                                          item.next = new CircularQueueItem(undefined, undefined, item);
                                          item = item.next;

                                          item.next = this._current;
                                          this._current.back = item;

                                          this.push = function (value)
                                          /// <summary>Pushes a value/object into the circular queue</summary>
                                          /// <param name="value">Any value/object that should be stored into the queue</param>
                                          this._current.value = value;
                                          this._current = this._current.next;
                                          ;
                                          this.pop = function ()
                                          /// <summary>Gets the last pushed value/object from the circular queue</summary>
                                          /// <returns>Returns the last pushed value/object from the circular queue</returns>
                                          this._current = this._current.back;
                                          return this._current.value;
                                          ;
                                          return this;



                                          To use:



                                           var queue = new CircularQueue(3); // a circular queue with 3 items
                                          queue.push("a");
                                          queue.push("b");
                                          queue.push("c");
                                          queue.push("d");
                                          alert(queue.pop()); // d
                                          alert(queue.pop()); // c
                                          alert(queue.pop()); // b
                                          alert(queue.pop()); // d
                                          alert(queue.pop()); // c





                                          share|improve this answer























                                          • Because it's a queue and not a stack, should pop() return the first added element instead of the last one? Am I missing something here? For example imagine we have Mike, Lauren and a ticketing booth queue. Mike joins to the end of the queue. After Mike Lauren joins in. Because the queue, Mike will be served first.

                                            – Akseli Palén
                                            Feb 16 '13 at 21:36













                                          1












                                          1








                                          1







                                          I couldn't get Robert Koritnik's code to work, so I edited it to the following which seems to work:



                                           var CircularQueueItem = function (value, next, back) 
                                          this.next = next;
                                          this.value = value;
                                          this.back = back;
                                          return this;
                                          ;

                                          var CircularQueue = function (queueLength)
                                          /// <summary>Creates a circular queue of specified length</summary>
                                          /// <param name="queueLength" type="int">Length of the circular queue</type>
                                          this._current = new CircularQueueItem(undefined, undefined, undefined);
                                          var item = this._current;
                                          for (var i = 0; i < queueLength - 1; i++)
                                          item.next = new CircularQueueItem(undefined, undefined, item);
                                          item = item.next;

                                          item.next = this._current;
                                          this._current.back = item;

                                          this.push = function (value)
                                          /// <summary>Pushes a value/object into the circular queue</summary>
                                          /// <param name="value">Any value/object that should be stored into the queue</param>
                                          this._current.value = value;
                                          this._current = this._current.next;
                                          ;
                                          this.pop = function ()
                                          /// <summary>Gets the last pushed value/object from the circular queue</summary>
                                          /// <returns>Returns the last pushed value/object from the circular queue</returns>
                                          this._current = this._current.back;
                                          return this._current.value;
                                          ;
                                          return this;



                                          To use:



                                           var queue = new CircularQueue(3); // a circular queue with 3 items
                                          queue.push("a");
                                          queue.push("b");
                                          queue.push("c");
                                          queue.push("d");
                                          alert(queue.pop()); // d
                                          alert(queue.pop()); // c
                                          alert(queue.pop()); // b
                                          alert(queue.pop()); // d
                                          alert(queue.pop()); // c





                                          share|improve this answer













                                          I couldn't get Robert Koritnik's code to work, so I edited it to the following which seems to work:



                                           var CircularQueueItem = function (value, next, back) 
                                          this.next = next;
                                          this.value = value;
                                          this.back = back;
                                          return this;
                                          ;

                                          var CircularQueue = function (queueLength)
                                          /// <summary>Creates a circular queue of specified length</summary>
                                          /// <param name="queueLength" type="int">Length of the circular queue</type>
                                          this._current = new CircularQueueItem(undefined, undefined, undefined);
                                          var item = this._current;
                                          for (var i = 0; i < queueLength - 1; i++)
                                          item.next = new CircularQueueItem(undefined, undefined, item);
                                          item = item.next;

                                          item.next = this._current;
                                          this._current.back = item;

                                          this.push = function (value)
                                          /// <summary>Pushes a value/object into the circular queue</summary>
                                          /// <param name="value">Any value/object that should be stored into the queue</param>
                                          this._current.value = value;
                                          this._current = this._current.next;
                                          ;
                                          this.pop = function ()
                                          /// <summary>Gets the last pushed value/object from the circular queue</summary>
                                          /// <returns>Returns the last pushed value/object from the circular queue</returns>
                                          this._current = this._current.back;
                                          return this._current.value;
                                          ;
                                          return this;



                                          To use:



                                           var queue = new CircularQueue(3); // a circular queue with 3 items
                                          queue.push("a");
                                          queue.push("b");
                                          queue.push("c");
                                          queue.push("d");
                                          alert(queue.pop()); // d
                                          alert(queue.pop()); // c
                                          alert(queue.pop()); // b
                                          alert(queue.pop()); // d
                                          alert(queue.pop()); // c






                                          share|improve this answer












                                          share|improve this answer



                                          share|improve this answer










                                          answered May 28 '10 at 17:19









                                          Mr. FlibbleMr. Flibble

                                          11.9k196096




                                          11.9k196096












                                          • Because it's a queue and not a stack, should pop() return the first added element instead of the last one? Am I missing something here? For example imagine we have Mike, Lauren and a ticketing booth queue. Mike joins to the end of the queue. After Mike Lauren joins in. Because the queue, Mike will be served first.

                                            – Akseli Palén
                                            Feb 16 '13 at 21:36

















                                          • Because it's a queue and not a stack, should pop() return the first added element instead of the last one? Am I missing something here? For example imagine we have Mike, Lauren and a ticketing booth queue. Mike joins to the end of the queue. After Mike Lauren joins in. Because the queue, Mike will be served first.

                                            – Akseli Palén
                                            Feb 16 '13 at 21:36
















                                          Because it's a queue and not a stack, should pop() return the first added element instead of the last one? Am I missing something here? For example imagine we have Mike, Lauren and a ticketing booth queue. Mike joins to the end of the queue. After Mike Lauren joins in. Because the queue, Mike will be served first.

                                          – Akseli Palén
                                          Feb 16 '13 at 21:36





                                          Because it's a queue and not a stack, should pop() return the first added element instead of the last one? Am I missing something here? For example imagine we have Mike, Lauren and a ticketing booth queue. Mike joins to the end of the queue. After Mike Lauren joins in. Because the queue, Mike will be served first.

                                          – Akseli Palén
                                          Feb 16 '13 at 21:36











                                          1














                                          I really like how noiv11 solved this and for my need I added an extra property 'buffer' which returns the buffer:



                                          var createRingBuffer = function(length)

                                          var pointer = 0, buffer = ;

                                          return
                                          get : function(key)return buffer[key];,
                                          push : function(item)
                                          buffer[pointer] = item;
                                          pointer = (length + pointer +1) % length;
                                          ,
                                          buffer : buffer
                                          ;
                                          ;

                                          // sample use
                                          var rbuffer = createRingBuffer(3);
                                          rbuffer.push('a');
                                          rbuffer.push('b');
                                          rbuffer.push('c');
                                          alert(rbuffer.buffer.toString());
                                          rbuffer.push('d');
                                          alert(rbuffer.buffer.toString());
                                          var el = rbuffer.get(0);
                                          alert(el);





                                          share|improve this answer

























                                          • What a horrible thing to do! The buffer was nicely hidden in the original.

                                            – James
                                            Jul 24 '14 at 18:42






                                          • 2





                                            Agree, no idea why I did it (2 years ago)

                                            – soderlind
                                            Jul 31 '14 at 20:38















                                          1














                                          I really like how noiv11 solved this and for my need I added an extra property 'buffer' which returns the buffer:



                                          var createRingBuffer = function(length)

                                          var pointer = 0, buffer = ;

                                          return
                                          get : function(key)return buffer[key];,
                                          push : function(item)
                                          buffer[pointer] = item;
                                          pointer = (length + pointer +1) % length;
                                          ,
                                          buffer : buffer
                                          ;
                                          ;

                                          // sample use
                                          var rbuffer = createRingBuffer(3);
                                          rbuffer.push('a');
                                          rbuffer.push('b');
                                          rbuffer.push('c');
                                          alert(rbuffer.buffer.toString());
                                          rbuffer.push('d');
                                          alert(rbuffer.buffer.toString());
                                          var el = rbuffer.get(0);
                                          alert(el);





                                          share|improve this answer

























                                          • What a horrible thing to do! The buffer was nicely hidden in the original.

                                            – James
                                            Jul 24 '14 at 18:42






                                          • 2





                                            Agree, no idea why I did it (2 years ago)

                                            – soderlind
                                            Jul 31 '14 at 20:38













                                          1












                                          1








                                          1







                                          I really like how noiv11 solved this and for my need I added an extra property 'buffer' which returns the buffer:



                                          var createRingBuffer = function(length)

                                          var pointer = 0, buffer = ;

                                          return
                                          get : function(key)return buffer[key];,
                                          push : function(item)
                                          buffer[pointer] = item;
                                          pointer = (length + pointer +1) % length;
                                          ,
                                          buffer : buffer
                                          ;
                                          ;

                                          // sample use
                                          var rbuffer = createRingBuffer(3);
                                          rbuffer.push('a');
                                          rbuffer.push('b');
                                          rbuffer.push('c');
                                          alert(rbuffer.buffer.toString());
                                          rbuffer.push('d');
                                          alert(rbuffer.buffer.toString());
                                          var el = rbuffer.get(0);
                                          alert(el);





                                          share|improve this answer















                                          I really like how noiv11 solved this and for my need I added an extra property 'buffer' which returns the buffer:



                                          var createRingBuffer = function(length)

                                          var pointer = 0, buffer = ;

                                          return
                                          get : function(key)return buffer[key];,
                                          push : function(item)
                                          buffer[pointer] = item;
                                          pointer = (length + pointer +1) % length;
                                          ,
                                          buffer : buffer
                                          ;
                                          ;

                                          // sample use
                                          var rbuffer = createRingBuffer(3);
                                          rbuffer.push('a');
                                          rbuffer.push('b');
                                          rbuffer.push('c');
                                          alert(rbuffer.buffer.toString());
                                          rbuffer.push('d');
                                          alert(rbuffer.buffer.toString());
                                          var el = rbuffer.get(0);
                                          alert(el);






                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          edited May 23 '17 at 12:02









                                          Community

                                          11




                                          11










                                          answered Jun 12 '12 at 12:12









                                          soderlindsoderlind

                                          34915




                                          34915












                                          • What a horrible thing to do! The buffer was nicely hidden in the original.

                                            – James
                                            Jul 24 '14 at 18:42






                                          • 2





                                            Agree, no idea why I did it (2 years ago)

                                            – soderlind
                                            Jul 31 '14 at 20:38

















                                          • What a horrible thing to do! The buffer was nicely hidden in the original.

                                            – James
                                            Jul 24 '14 at 18:42






                                          • 2





                                            Agree, no idea why I did it (2 years ago)

                                            – soderlind
                                            Jul 31 '14 at 20:38
















                                          What a horrible thing to do! The buffer was nicely hidden in the original.

                                          – James
                                          Jul 24 '14 at 18:42





                                          What a horrible thing to do! The buffer was nicely hidden in the original.

                                          – James
                                          Jul 24 '14 at 18:42




                                          2




                                          2





                                          Agree, no idea why I did it (2 years ago)

                                          – soderlind
                                          Jul 31 '14 at 20:38





                                          Agree, no idea why I did it (2 years ago)

                                          – soderlind
                                          Jul 31 '14 at 20:38











                                          1














                                          Instead of implementing circular queue with JavaScript, we can use some inbuilt functions of array to achieve circular queue implementation.



                                          example:
                                          Suppose we need to implement the circular queue for length 4.



                                          var circular = new Array();
                                          var maxLength = 4;
                                          var addElementToQueue = function(element)
                                          if(circular.length == maxLength)
                                          circular.pop();

                                          circular.unshift(element);
                                          ;
                                          addElementToQueue(1);
                                          addElementToQueue(2);
                                          addElementToQueue(3);
                                          addElementToQueue(4);


                                          Output:



                                          circular
                                          [4, 3, 2, 1]



                                          If you try to add another element to this array eg:



                                          addElementToQueue(5);


                                          Output:



                                          circular
                                          [5, 4, 3, 2]






                                          share|improve this answer



























                                            1














                                            Instead of implementing circular queue with JavaScript, we can use some inbuilt functions of array to achieve circular queue implementation.



                                            example:
                                            Suppose we need to implement the circular queue for length 4.



                                            var circular = new Array();
                                            var maxLength = 4;
                                            var addElementToQueue = function(element)
                                            if(circular.length == maxLength)
                                            circular.pop();

                                            circular.unshift(element);
                                            ;
                                            addElementToQueue(1);
                                            addElementToQueue(2);
                                            addElementToQueue(3);
                                            addElementToQueue(4);


                                            Output:



                                            circular
                                            [4, 3, 2, 1]



                                            If you try to add another element to this array eg:



                                            addElementToQueue(5);


                                            Output:



                                            circular
                                            [5, 4, 3, 2]






                                            share|improve this answer

























                                              1












                                              1








                                              1







                                              Instead of implementing circular queue with JavaScript, we can use some inbuilt functions of array to achieve circular queue implementation.



                                              example:
                                              Suppose we need to implement the circular queue for length 4.



                                              var circular = new Array();
                                              var maxLength = 4;
                                              var addElementToQueue = function(element)
                                              if(circular.length == maxLength)
                                              circular.pop();

                                              circular.unshift(element);
                                              ;
                                              addElementToQueue(1);
                                              addElementToQueue(2);
                                              addElementToQueue(3);
                                              addElementToQueue(4);


                                              Output:



                                              circular
                                              [4, 3, 2, 1]



                                              If you try to add another element to this array eg:



                                              addElementToQueue(5);


                                              Output:



                                              circular
                                              [5, 4, 3, 2]






                                              share|improve this answer













                                              Instead of implementing circular queue with JavaScript, we can use some inbuilt functions of array to achieve circular queue implementation.



                                              example:
                                              Suppose we need to implement the circular queue for length 4.



                                              var circular = new Array();
                                              var maxLength = 4;
                                              var addElementToQueue = function(element)
                                              if(circular.length == maxLength)
                                              circular.pop();

                                              circular.unshift(element);
                                              ;
                                              addElementToQueue(1);
                                              addElementToQueue(2);
                                              addElementToQueue(3);
                                              addElementToQueue(4);


                                              Output:



                                              circular
                                              [4, 3, 2, 1]



                                              If you try to add another element to this array eg:



                                              addElementToQueue(5);


                                              Output:



                                              circular
                                              [5, 4, 3, 2]







                                              share|improve this answer












                                              share|improve this answer



                                              share|improve this answer










                                              answered Nov 9 '15 at 11:44









                                              PuneetPuneet

                                              19011




                                              19011





















                                                  0














                                                  One approach would be to use a linked list as others have suggested. Another technique would be to use a simple array as the buffer and to keep track of the read and write positions via indices into that array.






                                                  share|improve this answer



























                                                    0














                                                    One approach would be to use a linked list as others have suggested. Another technique would be to use a simple array as the buffer and to keep track of the read and write positions via indices into that array.






                                                    share|improve this answer

























                                                      0












                                                      0








                                                      0







                                                      One approach would be to use a linked list as others have suggested. Another technique would be to use a simple array as the buffer and to keep track of the read and write positions via indices into that array.






                                                      share|improve this answer













                                                      One approach would be to use a linked list as others have suggested. Another technique would be to use a simple array as the buffer and to keep track of the read and write positions via indices into that array.







                                                      share|improve this answer












                                                      share|improve this answer



                                                      share|improve this answer










                                                      answered Oct 17 '09 at 21:23









                                                      user191817user191817

                                                      91




                                                      91





















                                                          0














                                                          I think you should be able to do this by just using objects. Something like this:



                                                          var link = function(next, value) 
                                                          this.next = next;
                                                          this.value = value;
                                                          ;

                                                          var last = new link();
                                                          var second = link(last);
                                                          var first = link(second);
                                                          last.next = first;


                                                          Now you'd just store the value in each link's value property.






                                                          share|improve this answer




















                                                          • 1





                                                            I believe you forgot to use the new operator.

                                                            – Ionuț G. Stan
                                                            Oct 17 '09 at 21:31











                                                          • Yep, been coding too much Python as of late =)

                                                            – Jani Hartikainen
                                                            Oct 17 '09 at 23:28











                                                          • lol linked lists your code appears C++

                                                            – ShrekOverflow
                                                            Feb 10 '12 at 18:14















                                                          0














                                                          I think you should be able to do this by just using objects. Something like this:



                                                          var link = function(next, value) 
                                                          this.next = next;
                                                          this.value = value;
                                                          ;

                                                          var last = new link();
                                                          var second = link(last);
                                                          var first = link(second);
                                                          last.next = first;


                                                          Now you'd just store the value in each link's value property.






                                                          share|improve this answer




















                                                          • 1





                                                            I believe you forgot to use the new operator.

                                                            – Ionuț G. Stan
                                                            Oct 17 '09 at 21:31











                                                          • Yep, been coding too much Python as of late =)

                                                            – Jani Hartikainen
                                                            Oct 17 '09 at 23:28











                                                          • lol linked lists your code appears C++

                                                            – ShrekOverflow
                                                            Feb 10 '12 at 18:14













                                                          0












                                                          0








                                                          0







                                                          I think you should be able to do this by just using objects. Something like this:



                                                          var link = function(next, value) 
                                                          this.next = next;
                                                          this.value = value;
                                                          ;

                                                          var last = new link();
                                                          var second = link(last);
                                                          var first = link(second);
                                                          last.next = first;


                                                          Now you'd just store the value in each link's value property.






                                                          share|improve this answer















                                                          I think you should be able to do this by just using objects. Something like this:



                                                          var link = function(next, value) 
                                                          this.next = next;
                                                          this.value = value;
                                                          ;

                                                          var last = new link();
                                                          var second = link(last);
                                                          var first = link(second);
                                                          last.next = first;


                                                          Now you'd just store the value in each link's value property.







                                                          share|improve this answer














                                                          share|improve this answer



                                                          share|improve this answer








                                                          edited Oct 17 '09 at 21:54









                                                          Robert Koritnik

                                                          77.2k42241365




                                                          77.2k42241365










                                                          answered Oct 17 '09 at 20:38









                                                          Jani HartikainenJani Hartikainen

                                                          35.8k95580




                                                          35.8k95580







                                                          • 1





                                                            I believe you forgot to use the new operator.

                                                            – Ionuț G. Stan
                                                            Oct 17 '09 at 21:31











                                                          • Yep, been coding too much Python as of late =)

                                                            – Jani Hartikainen
                                                            Oct 17 '09 at 23:28











                                                          • lol linked lists your code appears C++

                                                            – ShrekOverflow
                                                            Feb 10 '12 at 18:14












                                                          • 1





                                                            I believe you forgot to use the new operator.

                                                            – Ionuț G. Stan
                                                            Oct 17 '09 at 21:31











                                                          • Yep, been coding too much Python as of late =)

                                                            – Jani Hartikainen
                                                            Oct 17 '09 at 23:28











                                                          • lol linked lists your code appears C++

                                                            – ShrekOverflow
                                                            Feb 10 '12 at 18:14







                                                          1




                                                          1





                                                          I believe you forgot to use the new operator.

                                                          – Ionuț G. Stan
                                                          Oct 17 '09 at 21:31





                                                          I believe you forgot to use the new operator.

                                                          – Ionuț G. Stan
                                                          Oct 17 '09 at 21:31













                                                          Yep, been coding too much Python as of late =)

                                                          – Jani Hartikainen
                                                          Oct 17 '09 at 23:28





                                                          Yep, been coding too much Python as of late =)

                                                          – Jani Hartikainen
                                                          Oct 17 '09 at 23:28













                                                          lol linked lists your code appears C++

                                                          – ShrekOverflow
                                                          Feb 10 '12 at 18:14





                                                          lol linked lists your code appears C++

                                                          – ShrekOverflow
                                                          Feb 10 '12 at 18:14











                                                          0














                                                          Thanks noiv for your simple and efficient solution. I also needed to be able to access the buffer like PerS did, but i wanted to get the items in the order they were added. So here's what i ended up with:



                                                          function buffer(capacity) 
                                                          if (!(capacity > 0))
                                                          throw new Error();


                                                          var pointer = 0, buffer = ;

                                                          var publicObj =
                                                          get: function (key)
                                                          if (key === undefined) buffer.length < capacity)
                                                          // the buffer as it is now is in order
                                                          return buffer;

                                                          // split and join the two parts so the result is in order
                                                          return buffer.slice(pointer).concat(buffer.slice(0, pointer));

                                                          return buffer[key];
                                                          ,
                                                          push: function (item)
                                                          buffer[pointer] = item;
                                                          pointer = (capacity + pointer + 1) % capacity;
                                                          // update public length field
                                                          publicObj.length = buffer.length;
                                                          ,
                                                          capacity: capacity,
                                                          length: 0
                                                          ;

                                                          return publicObj;



                                                          Here is the test suite:



                                                          QUnit.module("buffer");

                                                          QUnit.test("constructor", function ()
                                                          QUnit.expect(4);

                                                          QUnit.equal(buffer(1).capacity, 1, "minimum length of 1 is allowed");
                                                          QUnit.equal(buffer(10).capacity, 10);

                                                          QUnit.throws(
                                                          function ()
                                                          buffer(-1);
                                                          ,
                                                          Error,
                                                          "must throuw exception on negative length"
                                                          );

                                                          QUnit.throws(
                                                          function ()
                                                          buffer(0);
                                                          ,
                                                          Error,
                                                          "must throw exception on zero length"
                                                          );
                                                          );

                                                          QUnit.test("push", function ()
                                                          QUnit.expect(5);

                                                          var b = buffer(5);
                                                          QUnit.equal(b.length, 0);
                                                          b.push("1");
                                                          QUnit.equal(b.length, 1);
                                                          b.push("2");
                                                          b.push("3");
                                                          b.push("4");
                                                          b.push("5");
                                                          QUnit.equal(b.length, 5);
                                                          b.push("6");
                                                          QUnit.equal(b.length, 5);
                                                          b.push("7");
                                                          b.push("8");
                                                          QUnit.equal(b.length, 5);
                                                          );

                                                          QUnit.test("get(key)", function ()
                                                          QUnit.expect(8);

                                                          var b = buffer(3);
                                                          QUnit.equal(b.get(0), undefined);
                                                          b.push("a");
                                                          QUnit.equal(b.get(0), "a");
                                                          b.push("b");
                                                          QUnit.equal(b.get(1), "b");
                                                          b.push("c");
                                                          QUnit.equal(b.get(2), "c");
                                                          b.push("d");
                                                          QUnit.equal(b.get(0), "d");

                                                          b = buffer(1);
                                                          b.push("1");
                                                          QUnit.equal(b.get(0), "1");
                                                          b.push("2");
                                                          QUnit.equal(b.get(0), "2");
                                                          QUnit.equal(b.length, 1);
                                                          );

                                                          QUnit.test("get()", function ()
                                                          QUnit.expect(7);

                                                          var b = buffer(3);
                                                          QUnit.deepEqual(b.get(), );
                                                          b.push("a");
                                                          QUnit.deepEqual(b.get(), ["a"]);
                                                          b.push("b");
                                                          QUnit.deepEqual(b.get(), ["a", "b"]);
                                                          b.push("c");
                                                          QUnit.deepEqual(b.get(), ["a", "b", "c"]);
                                                          b.push("d");
                                                          QUnit.deepEqual(b.get(), ["b", "c", "d"]);
                                                          b.push("e");
                                                          QUnit.deepEqual(b.get(), ["c", "d", "e"]);
                                                          b.push("f");
                                                          QUnit.deepEqual(b.get(), ["d", "e", "f"]);
                                                          );





                                                          share|improve this answer





























                                                            0














                                                            Thanks noiv for your simple and efficient solution. I also needed to be able to access the buffer like PerS did, but i wanted to get the items in the order they were added. So here's what i ended up with:



                                                            function buffer(capacity) 
                                                            if (!(capacity > 0))
                                                            throw new Error();


                                                            var pointer = 0, buffer = ;

                                                            var publicObj =
                                                            get: function (key)
                                                            if (key === undefined) buffer.length < capacity)
                                                            // the buffer as it is now is in order
                                                            return buffer;

                                                            // split and join the two parts so the result is in order
                                                            return buffer.slice(pointer).concat(buffer.slice(0, pointer));

                                                            return buffer[key];
                                                            ,
                                                            push: function (item)
                                                            buffer[pointer] = item;
                                                            pointer = (capacity + pointer + 1) % capacity;
                                                            // update public length field
                                                            publicObj.length = buffer.length;
                                                            ,
                                                            capacity: capacity,
                                                            length: 0
                                                            ;

                                                            return publicObj;



                                                            Here is the test suite:



                                                            QUnit.module("buffer");

                                                            QUnit.test("constructor", function ()
                                                            QUnit.expect(4);

                                                            QUnit.equal(buffer(1).capacity, 1, "minimum length of 1 is allowed");
                                                            QUnit.equal(buffer(10).capacity, 10);

                                                            QUnit.throws(
                                                            function ()
                                                            buffer(-1);
                                                            ,
                                                            Error,
                                                            "must throuw exception on negative length"
                                                            );

                                                            QUnit.throws(
                                                            function ()
                                                            buffer(0);
                                                            ,
                                                            Error,
                                                            "must throw exception on zero length"
                                                            );
                                                            );

                                                            QUnit.test("push", function ()
                                                            QUnit.expect(5);

                                                            var b = buffer(5);
                                                            QUnit.equal(b.length, 0);
                                                            b.push("1");
                                                            QUnit.equal(b.length, 1);
                                                            b.push("2");
                                                            b.push("3");
                                                            b.push("4");
                                                            b.push("5");
                                                            QUnit.equal(b.length, 5);
                                                            b.push("6");
                                                            QUnit.equal(b.length, 5);
                                                            b.push("7");
                                                            b.push("8");
                                                            QUnit.equal(b.length, 5);
                                                            );

                                                            QUnit.test("get(key)", function ()
                                                            QUnit.expect(8);

                                                            var b = buffer(3);
                                                            QUnit.equal(b.get(0), undefined);
                                                            b.push("a");
                                                            QUnit.equal(b.get(0), "a");
                                                            b.push("b");
                                                            QUnit.equal(b.get(1), "b");
                                                            b.push("c");
                                                            QUnit.equal(b.get(2), "c");
                                                            b.push("d");
                                                            QUnit.equal(b.get(0), "d");

                                                            b = buffer(1);
                                                            b.push("1");
                                                            QUnit.equal(b.get(0), "1");
                                                            b.push("2");
                                                            QUnit.equal(b.get(0), "2");
                                                            QUnit.equal(b.length, 1);
                                                            );

                                                            QUnit.test("get()", function ()
                                                            QUnit.expect(7);

                                                            var b = buffer(3);
                                                            QUnit.deepEqual(b.get(), );
                                                            b.push("a");
                                                            QUnit.deepEqual(b.get(), ["a"]);
                                                            b.push("b");
                                                            QUnit.deepEqual(b.get(), ["a", "b"]);
                                                            b.push("c");
                                                            QUnit.deepEqual(b.get(), ["a", "b", "c"]);
                                                            b.push("d");
                                                            QUnit.deepEqual(b.get(), ["b", "c", "d"]);
                                                            b.push("e");
                                                            QUnit.deepEqual(b.get(), ["c", "d", "e"]);
                                                            b.push("f");
                                                            QUnit.deepEqual(b.get(), ["d", "e", "f"]);
                                                            );





                                                            share|improve this answer



























                                                              0












                                                              0








                                                              0







                                                              Thanks noiv for your simple and efficient solution. I also needed to be able to access the buffer like PerS did, but i wanted to get the items in the order they were added. So here's what i ended up with:



                                                              function buffer(capacity) 
                                                              if (!(capacity > 0))
                                                              throw new Error();


                                                              var pointer = 0, buffer = ;

                                                              var publicObj =
                                                              get: function (key)
                                                              if (key === undefined) buffer.length < capacity)
                                                              // the buffer as it is now is in order
                                                              return buffer;

                                                              // split and join the two parts so the result is in order
                                                              return buffer.slice(pointer).concat(buffer.slice(0, pointer));

                                                              return buffer[key];
                                                              ,
                                                              push: function (item)
                                                              buffer[pointer] = item;
                                                              pointer = (capacity + pointer + 1) % capacity;
                                                              // update public length field
                                                              publicObj.length = buffer.length;
                                                              ,
                                                              capacity: capacity,
                                                              length: 0
                                                              ;

                                                              return publicObj;



                                                              Here is the test suite:



                                                              QUnit.module("buffer");

                                                              QUnit.test("constructor", function ()
                                                              QUnit.expect(4);

                                                              QUnit.equal(buffer(1).capacity, 1, "minimum length of 1 is allowed");
                                                              QUnit.equal(buffer(10).capacity, 10);

                                                              QUnit.throws(
                                                              function ()
                                                              buffer(-1);
                                                              ,
                                                              Error,
                                                              "must throuw exception on negative length"
                                                              );

                                                              QUnit.throws(
                                                              function ()
                                                              buffer(0);
                                                              ,
                                                              Error,
                                                              "must throw exception on zero length"
                                                              );
                                                              );

                                                              QUnit.test("push", function ()
                                                              QUnit.expect(5);

                                                              var b = buffer(5);
                                                              QUnit.equal(b.length, 0);
                                                              b.push("1");
                                                              QUnit.equal(b.length, 1);
                                                              b.push("2");
                                                              b.push("3");
                                                              b.push("4");
                                                              b.push("5");
                                                              QUnit.equal(b.length, 5);
                                                              b.push("6");
                                                              QUnit.equal(b.length, 5);
                                                              b.push("7");
                                                              b.push("8");
                                                              QUnit.equal(b.length, 5);
                                                              );

                                                              QUnit.test("get(key)", function ()
                                                              QUnit.expect(8);

                                                              var b = buffer(3);
                                                              QUnit.equal(b.get(0), undefined);
                                                              b.push("a");
                                                              QUnit.equal(b.get(0), "a");
                                                              b.push("b");
                                                              QUnit.equal(b.get(1), "b");
                                                              b.push("c");
                                                              QUnit.equal(b.get(2), "c");
                                                              b.push("d");
                                                              QUnit.equal(b.get(0), "d");

                                                              b = buffer(1);
                                                              b.push("1");
                                                              QUnit.equal(b.get(0), "1");
                                                              b.push("2");
                                                              QUnit.equal(b.get(0), "2");
                                                              QUnit.equal(b.length, 1);
                                                              );

                                                              QUnit.test("get()", function ()
                                                              QUnit.expect(7);

                                                              var b = buffer(3);
                                                              QUnit.deepEqual(b.get(), );
                                                              b.push("a");
                                                              QUnit.deepEqual(b.get(), ["a"]);
                                                              b.push("b");
                                                              QUnit.deepEqual(b.get(), ["a", "b"]);
                                                              b.push("c");
                                                              QUnit.deepEqual(b.get(), ["a", "b", "c"]);
                                                              b.push("d");
                                                              QUnit.deepEqual(b.get(), ["b", "c", "d"]);
                                                              b.push("e");
                                                              QUnit.deepEqual(b.get(), ["c", "d", "e"]);
                                                              b.push("f");
                                                              QUnit.deepEqual(b.get(), ["d", "e", "f"]);
                                                              );





                                                              share|improve this answer















                                                              Thanks noiv for your simple and efficient solution. I also needed to be able to access the buffer like PerS did, but i wanted to get the items in the order they were added. So here's what i ended up with:



                                                              function buffer(capacity) 
                                                              if (!(capacity > 0))
                                                              throw new Error();


                                                              var pointer = 0, buffer = ;

                                                              var publicObj =
                                                              get: function (key)
                                                              if (key === undefined) buffer.length < capacity)
                                                              // the buffer as it is now is in order
                                                              return buffer;

                                                              // split and join the two parts so the result is in order
                                                              return buffer.slice(pointer).concat(buffer.slice(0, pointer));

                                                              return buffer[key];
                                                              ,
                                                              push: function (item)
                                                              buffer[pointer] = item;
                                                              pointer = (capacity + pointer + 1) % capacity;
                                                              // update public length field
                                                              publicObj.length = buffer.length;
                                                              ,
                                                              capacity: capacity,
                                                              length: 0
                                                              ;

                                                              return publicObj;



                                                              Here is the test suite:



                                                              QUnit.module("buffer");

                                                              QUnit.test("constructor", function ()
                                                              QUnit.expect(4);

                                                              QUnit.equal(buffer(1).capacity, 1, "minimum length of 1 is allowed");
                                                              QUnit.equal(buffer(10).capacity, 10);

                                                              QUnit.throws(
                                                              function ()
                                                              buffer(-1);
                                                              ,
                                                              Error,
                                                              "must throuw exception on negative length"
                                                              );

                                                              QUnit.throws(
                                                              function ()
                                                              buffer(0);
                                                              ,
                                                              Error,
                                                              "must throw exception on zero length"
                                                              );
                                                              );

                                                              QUnit.test("push", function ()
                                                              QUnit.expect(5);

                                                              var b = buffer(5);
                                                              QUnit.equal(b.length, 0);
                                                              b.push("1");
                                                              QUnit.equal(b.length, 1);
                                                              b.push("2");
                                                              b.push("3");
                                                              b.push("4");
                                                              b.push("5");
                                                              QUnit.equal(b.length, 5);
                                                              b.push("6");
                                                              QUnit.equal(b.length, 5);
                                                              b.push("7");
                                                              b.push("8");
                                                              QUnit.equal(b.length, 5);
                                                              );

                                                              QUnit.test("get(key)", function ()
                                                              QUnit.expect(8);

                                                              var b = buffer(3);
                                                              QUnit.equal(b.get(0), undefined);
                                                              b.push("a");
                                                              QUnit.equal(b.get(0), "a");
                                                              b.push("b");
                                                              QUnit.equal(b.get(1), "b");
                                                              b.push("c");
                                                              QUnit.equal(b.get(2), "c");
                                                              b.push("d");
                                                              QUnit.equal(b.get(0), "d");

                                                              b = buffer(1);
                                                              b.push("1");
                                                              QUnit.equal(b.get(0), "1");
                                                              b.push("2");
                                                              QUnit.equal(b.get(0), "2");
                                                              QUnit.equal(b.length, 1);
                                                              );

                                                              QUnit.test("get()", function ()
                                                              QUnit.expect(7);

                                                              var b = buffer(3);
                                                              QUnit.deepEqual(b.get(), );
                                                              b.push("a");
                                                              QUnit.deepEqual(b.get(), ["a"]);
                                                              b.push("b");
                                                              QUnit.deepEqual(b.get(), ["a", "b"]);
                                                              b.push("c");
                                                              QUnit.deepEqual(b.get(), ["a", "b", "c"]);
                                                              b.push("d");
                                                              QUnit.deepEqual(b.get(), ["b", "c", "d"]);
                                                              b.push("e");
                                                              QUnit.deepEqual(b.get(), ["c", "d", "e"]);
                                                              b.push("f");
                                                              QUnit.deepEqual(b.get(), ["d", "e", "f"]);
                                                              );






                                                              share|improve this answer














                                                              share|improve this answer



                                                              share|improve this answer








                                                              edited May 23 '17 at 12:17









                                                              Community

                                                              11




                                                              11










                                                              answered May 14 '13 at 4:07









                                                              MuxaMuxa

                                                              3,42763854




                                                              3,42763854





















                                                                  0














                                                                  Shameless self plug:



                                                                  If you are looking for a rotating node.js buffer, I wrote one that can be found here: http://npmjs.org/packages/pivot-buffer



                                                                  Documentation is currently lacking, but RotatingBuffer#push allows you to append a buffer to the current buffer, rotating the previous data if new length is greater than the length specified in the constructor.






                                                                  share|improve this answer



























                                                                    0














                                                                    Shameless self plug:



                                                                    If you are looking for a rotating node.js buffer, I wrote one that can be found here: http://npmjs.org/packages/pivot-buffer



                                                                    Documentation is currently lacking, but RotatingBuffer#push allows you to append a buffer to the current buffer, rotating the previous data if new length is greater than the length specified in the constructor.






                                                                    share|improve this answer

























                                                                      0












                                                                      0








                                                                      0







                                                                      Shameless self plug:



                                                                      If you are looking for a rotating node.js buffer, I wrote one that can be found here: http://npmjs.org/packages/pivot-buffer



                                                                      Documentation is currently lacking, but RotatingBuffer#push allows you to append a buffer to the current buffer, rotating the previous data if new length is greater than the length specified in the constructor.






                                                                      share|improve this answer













                                                                      Shameless self plug:



                                                                      If you are looking for a rotating node.js buffer, I wrote one that can be found here: http://npmjs.org/packages/pivot-buffer



                                                                      Documentation is currently lacking, but RotatingBuffer#push allows you to append a buffer to the current buffer, rotating the previous data if new length is greater than the length specified in the constructor.







                                                                      share|improve this answer












                                                                      share|improve this answer



                                                                      share|improve this answer










                                                                      answered Dec 16 '15 at 9:59









                                                                      Yotam OfekYotam Ofek

                                                                      956915




                                                                      956915





















                                                                          0














                                                                          Its very easy if you now what Array.prototype.length is:



                                                                          function CircularBuffer(size) 
                                                                          Array.call(this,size); //superclass
                                                                          this.length = 0; //current index
                                                                          this.size = size; //buffer size
                                                                          ;

                                                                          CircularBuffer.prototype = Object.create(Array.prototype);
                                                                          CircularBuffer.prototype.constructor = CircularBuffer;
                                                                          CircularBuffer.prototype.constructor.name = "CircularBuffer";

                                                                          CircularBuffer.prototype.push = function push(elem)
                                                                          Array.prototype.push.call(this,elem);
                                                                          if (this.length >= this.size) this.length = 0;
                                                                          return this.length;


                                                                          CircularBuffer.prototype.pop = function pop()
                                                                          var r = this[this.length];
                                                                          if (this.length <= 0) this.length = this.size;
                                                                          this.length--;
                                                                          return r;






                                                                          share|improve this answer





























                                                                            0














                                                                            Its very easy if you now what Array.prototype.length is:



                                                                            function CircularBuffer(size) 
                                                                            Array.call(this,size); //superclass
                                                                            this.length = 0; //current index
                                                                            this.size = size; //buffer size
                                                                            ;

                                                                            CircularBuffer.prototype = Object.create(Array.prototype);
                                                                            CircularBuffer.prototype.constructor = CircularBuffer;
                                                                            CircularBuffer.prototype.constructor.name = "CircularBuffer";

                                                                            CircularBuffer.prototype.push = function push(elem)
                                                                            Array.prototype.push.call(this,elem);
                                                                            if (this.length >= this.size) this.length = 0;
                                                                            return this.length;


                                                                            CircularBuffer.prototype.pop = function pop()
                                                                            var r = this[this.length];
                                                                            if (this.length <= 0) this.length = this.size;
                                                                            this.length--;
                                                                            return r;






                                                                            share|improve this answer



























                                                                              0












                                                                              0








                                                                              0







                                                                              Its very easy if you now what Array.prototype.length is:



                                                                              function CircularBuffer(size) 
                                                                              Array.call(this,size); //superclass
                                                                              this.length = 0; //current index
                                                                              this.size = size; //buffer size
                                                                              ;

                                                                              CircularBuffer.prototype = Object.create(Array.prototype);
                                                                              CircularBuffer.prototype.constructor = CircularBuffer;
                                                                              CircularBuffer.prototype.constructor.name = "CircularBuffer";

                                                                              CircularBuffer.prototype.push = function push(elem)
                                                                              Array.prototype.push.call(this,elem);
                                                                              if (this.length >= this.size) this.length = 0;
                                                                              return this.length;


                                                                              CircularBuffer.prototype.pop = function pop()
                                                                              var r = this[this.length];
                                                                              if (this.length <= 0) this.length = this.size;
                                                                              this.length--;
                                                                              return r;






                                                                              share|improve this answer















                                                                              Its very easy if you now what Array.prototype.length is:



                                                                              function CircularBuffer(size) 
                                                                              Array.call(this,size); //superclass
                                                                              this.length = 0; //current index
                                                                              this.size = size; //buffer size
                                                                              ;

                                                                              CircularBuffer.prototype = Object.create(Array.prototype);
                                                                              CircularBuffer.prototype.constructor = CircularBuffer;
                                                                              CircularBuffer.prototype.constructor.name = "CircularBuffer";

                                                                              CircularBuffer.prototype.push = function push(elem)
                                                                              Array.prototype.push.call(this,elem);
                                                                              if (this.length >= this.size) this.length = 0;
                                                                              return this.length;


                                                                              CircularBuffer.prototype.pop = function pop()
                                                                              var r = this[this.length];
                                                                              if (this.length <= 0) this.length = this.size;
                                                                              this.length--;
                                                                              return r;







                                                                              share|improve this answer














                                                                              share|improve this answer



                                                                              share|improve this answer








                                                                              edited Nov 14 '18 at 20:11

























                                                                              answered Nov 14 '18 at 19:45









                                                                              Uncle LeoUncle Leo

                                                                              102




                                                                              102



























                                                                                  draft saved

                                                                                  draft discarded
















































                                                                                  Thanks for contributing an answer to Stack Overflow!


                                                                                  • Please be sure to answer the question. Provide details and share your research!

                                                                                  But avoid


                                                                                  • Asking for help, clarification, or responding to other answers.

                                                                                  • Making statements based on opinion; back them up with references or personal experience.

                                                                                  To learn more, see our tips on writing great answers.




                                                                                  draft saved


                                                                                  draft discarded














                                                                                  StackExchange.ready(
                                                                                  function ()
                                                                                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1583123%2fcircular-buffer-in-javascript%23new-answer', 'question_page');

                                                                                  );

                                                                                  Post as a guest















                                                                                  Required, but never shown





















































                                                                                  Required, but never shown














                                                                                  Required, but never shown












                                                                                  Required, but never shown







                                                                                  Required, but never shown

































                                                                                  Required, but never shown














                                                                                  Required, but never shown












                                                                                  Required, but never shown







                                                                                  Required, but never shown







                                                                                  這個網誌中的熱門文章

                                                                                  What does pagestruct do in Eviews?

                                                                                  Dutch intervention in Lombok and Karangasem

                                                                                  Channel Islands