39

How can I get the first element from my stack here is my code

var stack = [];
stack.push(id1);
stack.push(id2);

I know there is something like peek in java. Is there any similar method in JS using which i can get the topmost element?

JustCurious
  • 780
  • 1
  • 10
  • 29
  • I don't think. Though you can either define yourself using `Array.prototype.peek = fn(){..}` or use custom function which would do `return arr[arr.length - 1]` – Rajesh Feb 28 '17 at 06:41
  • 4
    Ỳou mean like using `stack[0]`? – mauroc8 Feb 28 '17 at 06:42
  • @AndrewLi isn't `arr[arr.length -1]` better than doing 2 operation (*pop and push*) – Rajesh Feb 28 '17 at 06:42
  • @Rajesh wouldn't that give the last element? – Amresh Venugopal Feb 28 '17 at 06:48
  • 2
    If using slice is okay? what is wrong with `unshift()` – Amresh Venugopal Feb 28 '17 at 06:48
  • 1
    @AmreshVenugopal Isn't that what `peek` does? – Rajesh Feb 28 '17 at 06:50
  • @Rajesh I am not sure about `peek` but the question reads first element so I asked. :) – Amresh Venugopal Feb 28 '17 at 06:51
  • @AmreshVenugopal In stack, first element is the last 1 you pushed. Consider a stack of books. Which is the first book on top. Also your suggestion is correct about `unshift`. Also about `peek`, what would you do to read name of book on top? You would read it without moving it. – Rajesh Feb 28 '17 at 06:53
  • @Rajesh Thanks, now I get it. but then how is `unshift()` okay shouldn't it be `pop()`? but I think OP just wants to read and not modify his stack. so `arr[arr.length - 1]` is better suited. – Amresh Venugopal Feb 28 '17 at 06:57
  • @AmreshVenugopal My bad. Used a bad example to check it and got confused. Also `pop` is not ideal as it will remove last element and return it to you. – Rajesh Feb 28 '17 at 06:59
  • Unable to understand why not to use `stack[0]`? – Pardeep Jain Nov 16 '18 at 07:44
  • `stack[0]` returns the item at the *bottom* of the stack. `peek()` is meant to return the item on *top* of the stack. A peek function should return the last item you pushed to the stack, which will be at the end of the array. – snarf Aug 30 '20 at 18:04

6 Answers6

60

To check the topmost element unfortunately you must explicitly index it

var top = stack[stack.length-1];

the syntax stack[-1] (that would work in Python) doesn't work: negative indexes are valid only as parameters to slice call.

// The same as stack[stack.length-1], just slower and NOT idiomatic
var top = stack.slice(-1)[0];

To extract an element there is however pop:

// Add two top-most elements of the stack
var a = stack.pop();
var b = stack.pop();
stack.push(a + b);
6502
  • 112,025
  • 15
  • 165
  • 265
  • Chrome has `.getLast()` but obviously this is only on Chrome. – RozzA May 17 '18 at 21:35
  • but Why not to use `stack[0]`? – Pardeep Jain Nov 16 '18 at 07:50
  • 2
    @PardeepJain: because `push` and `pop` work on the last element of the array. Using `splice` to insert and removing elements from the beginning would make the two operations `O(n)` instead of `O(1)` (this is not strictly necessary as one could design a ring-buffer based array supporting amortized `O(1)` insertion at both ends and with `O(1)` removal at both ends and indexing, but it's not what common implementations do). – 6502 Nov 16 '18 at 10:17
  • thanks for comment but `stack[0]` will stay same right? – Pardeep Jain Nov 16 '18 at 10:24
  • @PardeepJain: `stack[0]` is the first element... if you want to remove it from the array either you make a loop or you write `stack.splice(0, 1)`. The latter however is in most implementations still a loop done by the Javascript runtime and therefore removing the first element requires `O(n)` time. – 6502 Nov 16 '18 at 13:59
  • Oh like that, yes got it. Thanks @6502 for information – Pardeep Jain Nov 16 '18 at 17:36
  • @RozzA, `getLast` isn't a thing. I assume you were either using a mixin or perhaps it existed at one point but no longer. – junvar Apr 08 '20 at 20:11
  • @6502 - Sorry if this is a noob question, but what did you mean "NOT Idiomatic"? – Krishnabm Sep 11 '21 at 13:43
  • 1
    @Krishnabm: it's not something you will find often in Javascript code... it's not a common pattern of this language. A javascript programmer would have to think understand what such an expression does... it's "weird". – 6502 Sep 11 '21 at 16:47
6

Edited 2022:

Now you can just use stack.at(-1)


If you just need one edge of your stack (head or tail is not matter) use it reversed:

I mean :

peek() become array[0],
unshift(v) become push()
shift() become pop()

some code:

class Stack{
  constructor(... args ){
    this.store = [... args.reverse()];
  }
  peek(){
    return this.store[0];
  }
  push(value){
    return this.store.unshift(value);
  }
  pop(){
   return this.store.shift();
  }
}

const stack = new Stack(1,2,3);
stack.push(4);
console.log(stack.peek());
stack.pop();
console.log(stack.peek())

or shorter

function Stack(...rest){
  var store = [... rest.reverse() ];
  return {
    push:(v)=> store.unshift(v) ,
    pop : _ => store.shift(),
    peek: _ => store[0]
    }
  }
  
var stack = Stack(1,2,3);
console.log(stack.peek());
stack.push(4);
console.log(stack.peek());
stack.pop(), stack.pop();
console.log(stack.peek());
pery mimon
  • 7,713
  • 6
  • 52
  • 57
  • i get it, but plz don't try to confuse ppl – user812954 Dec 19 '19 at 18:07
  • I'm not sure what you mean. looking at array on reverse order is a common way to solve various problems. – pery mimon Dec 21 '19 at 21:48
  • 1
    This is a terrible solution for any kind of stack/queue. Manipulating the end of an array is O(1), while manipulating the start of an array is O(n). So to gain a less clumsy `peek` you sacrifice the efficiency of the most common operations on a queue/stack -- `push` and `pop`. – Lawrence Dol May 21 '21 at 18:09
  • 1
    JS is not a real `array` is HASH or LINKING LIST – pery mimon May 23 '21 at 09:35
  • @perymimon That is not true. It depends on the implementation. Modern JS engines are smart enough to use a native backing array when the object is initialized and updated strictly like an array. For example, see [Elements kinds in V8](https://v8.dev/blog/elements-kinds). Even sparse arrays are supported these days very efficiently. – Inigo Apr 07 '22 at 22:35
  • Making a copy of the handed-in `...rest` arguments array is a good intention, but not necessary. The parameters array is created internally during the call, so no-one can reference this array and there is no need to copy it before modification. So just use `var store = rest.reverse()`. – YetAnotherFrank Feb 10 '23 at 23:20
  • What are the underscores at `pop` and `peek` are supposed to do? `_` is a legal variable/parameter name, so it looks as though both methods receive a parameter that is ignored. What you really want to express is an empty parameter list, `()`. Instead, you can leave out the parenthesis around `push`'s parameter `v`. – YetAnotherFrank Feb 10 '23 at 23:25
  • @YetAnotherFrank `_` is a just cleaner and short way to tell that I'm not using the parameter. one latter instead of two . and for me visualize, it look much cleaner – pery mimon Feb 19 '23 at 13:11
  • @perymimon My point is that these methods do not _have_ any parameter to ignore. – YetAnotherFrank Feb 22 '23 at 10:27
5

var stack = [];
stack.push("id1");
stack.push("id2");
console.log(stack[stack.length-1]); // the top element
console.log(stack.length); //size
Sagar V
  • 12,158
  • 7
  • 41
  • 68
2

I just want to add here the .at prototype function. Documentation is found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at

So, to get the peek is as simple as:

[array].at(-1);

Example:

const stack = [];
stack.push("sample1");
stack.push("sample2");

console.log(stack.at(-1)) // sample2
0

var stackArr = [1,2,3,4];

console.log(stackArr[stackArr.length-1]);
//expected output is 4;
Mobio
  • 11
  • 1
-3

        var stack = [];
        stack.push("id1");
        stack.push("id2");
        var topObj = stack[0]
       console.log(topObj)