1

How is

while (
  stack.peek() in ops &&
  p(stack.peek()) >= 10
) {
  str += stack.pop();
}

rewritten so I call .peek() every time the loop runs, but only define it once?

I have thought about

const peek = stack.peek();
while (
  peek in ops &&
  p(peek) >= 10
) {
  str += stack.pop();
}

but since I modify stack with stack.pop() inside the while loop, I guess the value of stack.peek() is changing every time, so I guess I have to redefine the variable inside the loop, but

let peek = stack.peek();
while (
  peek in ops &&
  p(peek) >= 10
) {
  str += stack.pop();
  peek = stack.peek();
}

also seems a bit wrong, so should it be something like

while (
  let peek = stack.peek() &&
  peek in ops &&
  p(peek) >= 10
) {
  str += stack.pop();
}

or

for (
  let peek = stack.peek();
  peek in ops && p(peek) >= 10;
  peek = stack.peek()
) {
  str += stack.pop();
}
6
  • 1
    Well, the second to last example is syntactically incorrect, so go with the for loop instead? Not clear to me what the issue is. Use whatever code works? Commented Sep 10, 2016 at 5:02
  • @Jamgreen. I gave it a shot. Let me know what you think. Commented Sep 10, 2016 at 5:11
  • @Jamgreen What do you mean by "but only define it once?" ? Commented Sep 10, 2016 at 5:15
  • I'm confused. Does stack contain functions? And so stack.peek() returns a function? So peek is a function? In that case, how can peek in ops make sense? Commented Sep 10, 2016 at 5:32
  • 1
    "Sorry for the consuion. I have created Array.prototype.peek = () => this[this.length - 1]. " Note, var stack = [1,2,3]; stack.peek() returned 3 , here, using function keyword . Array.prototype.peek = function() { return this[this.length - 1]} . var stack = [1,2,3]; Array.prototype.peek = () => this[this.length - 1]; stack.peek() returned undefined using arrow function. Commented Sep 10, 2016 at 7:02

3 Answers 3

1

Consider using while (true) with a break:

while (true) {
  const peek = stack.peek();
  if (!(peek in ops) || p(peek) < 10) break;
  str += stack.pop();
}

In theory you could also do:

while (
  (peek => peek in ops && p(peek) >= 10)(stack.peek())
) {
  str += stack.pop();
}

but that's pretty ugly. It's roughly equivalent to write

function pop(stack) {
  const peek = stack.peek();
  return peek in ops && p(peek) >= 10;
}

while(pop(stack)) str += stack.pop();

A for loop is not a bad idea either, and could be written as:

for (let peek; peek = stack.peek(), peek in ops && p(peek) >= 10; ) {
  str += stack.pop();
}

which again avoids duplicating the call to stack.peek().

Sign up to request clarification or add additional context in comments.

6 Comments

I did go with the while (true) approach :D I changed it to while (stack.length > 1) { const peek = stack.peek(); if (peek in ops && p(peek) >= 10) { str += stack.pop(); } else { break; } }.
@This seems over complicated. The solution is much, much, much, more simple.
@AnthonyRutledge The solutions provided do not appear to be more complicated than the original Question?
@guest271314 That is a strange justification for replacing simplicity with complexity.
@AnthonyRutledge Actually, it doesn't matter that much. However, as I interpreted the OP's question, it was about dealing with the unsatisfying nature of having two calls to stack.peek() in the code.
|
1

How is

while (
  stack.peek() in ops &&
  p(stack.peek()) >= 10
) {
  str += stack.pop();
}

rewritten so I call .peek() every time the loop runs, but only define it once?

Sorry for the consuion. I have created Array.prototype.peek = () => this[this.length - 1]. Is it bad practice to 'mess' with Array.prototype?

Note,

var stack = [1,2,3]; 
stack.peek();

returned 3 , here, using function keyword .

Array.prototype.peek = function() { return this[this.length - 1]}

using arrow function

Array.prototype.peek = () => this[this.length - 1]; stack.peek()

returned undefined


You could alternatively use expression stack.length -1 as condition within while loop; e.g.;

var stack = [-2, -1, 0, 1, 2, 3, 4, 5],
  n = 0;

while (stack.length - 1 && (peek = stack.pop())) {
  // do stuff
  n += (curr = peek * 10) >= 10 ? curr : n;
  delete curr;
  console.log(`peek:${peek}`);
}

console.log(`n:${n}, peek:${peek}`);

Comments

0

At minimum, this should work.

var peek = stack.peek();  //Declaration (once) and initialization

while ((peek in ops) && (p(peek) >= 10))
{
  str += stack.pop();
  peek = stack.peek()    //Re-assignment after modifying stack.
}

Define a variable before the loop condition, then update the variable as the last statement inside the loop. I'm sure you would have arrived at that solution eventually. :-)

1 Comment

This answer is the best answer, hands down.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.