-2

We know that Array.prototype.shift()/Array.prototype.unshift() are CPU intensive because they update all indices in an array. I want create a basic queue, and update an index.

class MyQueue {

 vals = [1,2,3];
 indexOfFirst = 0;

 shift(){
   const val = this.vals[this.indexOfFirst];
   delete this.vals[this.indexOfFirst];
   this.indexOfFirst++;
   return val;
 }

 unshift(val){
   this.indexOfFirst--;
   this.vals[this.indexOfFirst] = val;
 }

 pop(){
   return this.vals.pop()
 }

 push(v: any){
   return this.vals.push(v);
 }

}

would this work?

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • 1
    Did it work when you tried it? – Andy Dec 25 '22 at 11:18
  • It did work (I think) – Alexander Mills Dec 25 '22 at 11:21
  • One question is if the `delete` call is doing bad things – Alexander Mills Dec 25 '22 at 11:21
  • 1
    Delete function leaves a hole in the array. vals.length will remain 3, after delete. – Greg Kelesidis Dec 25 '22 at 11:36
  • Have you considered building this using a [doubly linked list](https://en.wikipedia.org/wiki/Doubly_linked_list) of nodes rather than using the built-in [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) type? – jsejcksn Dec 25 '22 at 12:14
  • @jsejcksn in this case would like to accomplish without a doubly linkedlist – Alexander Mills Dec 25 '22 at 22:58
  • [^](https://stackoverflow.com/questions/74912939/removing-items-from-front-of-array-without-using-shift#comment132207605_74912939) @AlexanderMills In that case, the question (["_would this work?_"](https://stackoverflow.com/revisions/74912939/2)) is unclear. What exactly is the criteria and what is the actual question? See [ask]. – jsejcksn Dec 26 '22 at 01:04

1 Answers1

0

It won't work in all scenarios. Here are 2 issues:

  1. if this.vals.length === 0 && this.indexOfFirst < 0 then push() and pop() won't behave as desired
  2. if this.indexOfFirst drops below Number.MIN_SAFE_INTEGER then unshift() will fail to add values to the queue

To fix the first issue you can use a Map instead of an Array along with a indexOfLast like you are already handling indexOfFirst:

class Queue {
  indexedVals = new Map();
  indexOfFirst = 0;
  indexOfLast = -1;

  constructor(vals) {
    if (vals) for (const val of vals) this.push(val);
  }

  shift() {
    if (this.indexOfFirst > this.indexOfLast) return;
    const val = this.indexedVals.get(this.indexOfFirst);
    this.indexedVals.delete(this.indexOfFirst++);
    return val;
  }

  unshift(val) {
    this.indexedVals.set(--this.indexOfFirst, val);
  }

  pop() {
    if (this.indexOfLast < this.indexOfFirst) return;
    const val = this.indexedVals.get(this.indexOfLast);
    this.indexedVals.delete(this.indexOfLast--);
    return val;
  }

  push(val) {
    this.indexedVals.set(++this.indexOfLast, val);
  }
}

To fix the second issue you can use BigInt instead of Number or you can implement a doubly-linked list where each node stores a value along with a pointer to the next and previous nodes (thereby avoiding any numeric limitations).

mfulton26
  • 29,956
  • 6
  • 64
  • 88