Circular buffer in JavaScript
Has anyone already implemented a circular buffer in JavaScript? How would you do that without having pointers?
javascript data-structures circular-buffer
add a comment |
Has anyone already implemented a circular buffer in JavaScript? How would you do that without having pointers?
javascript data-structures circular-buffer
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
add a comment |
Has anyone already implemented a circular buffer in JavaScript? How would you do that without having pointers?
javascript data-structures circular-buffer
Has anyone already implemented a circular buffer in JavaScript? How would you do that without having pointers?
javascript data-structures circular-buffer
javascript data-structures circular-buffer
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
add a comment |
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
add a comment |
14 Answers
14
active
oldest
votes
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= ;
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 somewhenInfinity. +1
– loveNoHate
Sep 8 '14 at 10:41
add a comment |
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);,
3
why do you havepointer = (length + pointer +1) % lengthinstead of justpointer = (pointer + 1) % length?
– Muxa
May 14 '13 at 3:19
Change get function toget : 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
add a comment |
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:
getsupports default argument (returns last item pushed onto buffer)getsupports negative indexing (counts from right)prevmoves buffer back one and returns what's there (like popping without delete)nextundoes 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.
add a comment |
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.
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
add a comment |
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 :-)
add a comment |
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
add a comment |
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
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
add a comment |
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);
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
add a comment |
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]
add a comment |
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.
add a comment |
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.
1
I believe you forgot to use thenewoperator.
– 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
add a comment |
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"]);
);
add a comment |
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.
add a comment |
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;
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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= ;
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 somewhenInfinity. +1
– loveNoHate
Sep 8 '14 at 10:41
add a comment |
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= ;
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 somewhenInfinity. +1
– loveNoHate
Sep 8 '14 at 10:41
add a comment |
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= ;
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= ;
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 somewhenInfinity. +1
– loveNoHate
Sep 8 '14 at 10:41
add a comment |
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 somewhenInfinity. +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
add a comment |
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);,
3
why do you havepointer = (length + pointer +1) % lengthinstead of justpointer = (pointer + 1) % length?
– Muxa
May 14 '13 at 3:19
Change get function toget : 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
add a comment |
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);,
3
why do you havepointer = (length + pointer +1) % lengthinstead of justpointer = (pointer + 1) % length?
– Muxa
May 14 '13 at 3:19
Change get function toget : 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
add a comment |
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);,
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);,
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 havepointer = (length + pointer +1) % lengthinstead of justpointer = (pointer + 1) % length?
– Muxa
May 14 '13 at 3:19
Change get function toget : 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
add a comment |
3
why do you havepointer = (length + pointer +1) % lengthinstead of justpointer = (pointer + 1) % length?
– Muxa
May 14 '13 at 3:19
Change get function toget : 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
add a comment |
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:
getsupports default argument (returns last item pushed onto buffer)getsupports negative indexing (counts from right)prevmoves buffer back one and returns what's there (like popping without delete)nextundoes 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.
add a comment |
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:
getsupports default argument (returns last item pushed onto buffer)getsupports negative indexing (counts from right)prevmoves buffer back one and returns what's there (like popping without delete)nextundoes 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.
add a comment |
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:
getsupports default argument (returns last item pushed onto buffer)getsupports negative indexing (counts from right)prevmoves buffer back one and returns what's there (like popping without delete)nextundoes 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.
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:
getsupports default argument (returns last item pushed onto buffer)getsupports negative indexing (counts from right)prevmoves buffer back one and returns what's there (like popping without delete)nextundoes 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.
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
add a comment |
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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 :-)
add a comment |
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 :-)
add a comment |
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 :-)
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 :-)
answered May 18 '14 at 9:45
laurentIsRunninglaurentIsRunning
888
888
add a comment |
add a comment |
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
add a comment |
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
add a comment |
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
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
answered Apr 2 '15 at 15:29
Oliver HeardOliver Heard
211
211
add a comment |
add a comment |
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
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
add a comment |
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
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
add a comment |
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
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
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
add a comment |
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
add a comment |
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);
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
add a comment |
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);
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
add a comment |
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);
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);
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
add a comment |
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
add a comment |
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]
add a comment |
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]
add a comment |
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]
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]
answered Nov 9 '15 at 11:44
PuneetPuneet
19011
19011
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Oct 17 '09 at 21:23
user191817user191817
91
91
add a comment |
add a comment |
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.
1
I believe you forgot to use thenewoperator.
– 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
add a comment |
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.
1
I believe you forgot to use thenewoperator.
– 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
add a comment |
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.
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.
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 thenewoperator.
– 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
add a comment |
1
I believe you forgot to use thenewoperator.
– 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
add a comment |
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"]);
);
add a comment |
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"]);
);
add a comment |
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"]);
);
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"]);
);
edited May 23 '17 at 12:17
Community♦
11
11
answered May 14 '13 at 4:07
MuxaMuxa
3,42763854
3,42763854
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Dec 16 '15 at 9:59
Yotam OfekYotam Ofek
956915
956915
add a comment |
add a comment |
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;
add a comment |
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;
add a comment |
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;
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;
edited Nov 14 '18 at 20:11
answered Nov 14 '18 at 19:45
Uncle LeoUncle Leo
102
102
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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