Stand In Line javaScript Exercise ! Stuck!


#101

This seems to work.

change the Parameters

of the function nextInLine (arr, item) to nextInline (testArr, item)

// Working Code

function nextInLine(testArr, item) {
  // Your code here
  testArr.push(item);
  return testArr.shift();  // Change this line
}

// Test Setup
var testArr = [1,2,3,4,5];

// Display Code
console.log("Before: " + JSON.stringify(testArr));
console.log(nextInLine(testArr, 6)); // Modify this line to test
console.log("After: " + JSON.stringify(testArr));


#102

muchas gracias / thank you so much


#103

I was stuck on this one as well, but I did like an earlier suggestion that made more sense for me:

function nextInLine(arr, item) {
// Your code here
arr.push(item);
var removed = arr.shift();

return removed; // Change this line
}

By actually declaring a variable named “removed” and setting it equal to arr.shift(), I could see the connection and was able to make more sense of it. It might be more code that I have to write, and could obviously be shortened, but for now as a newbie, it makes sense to write my code this way.


#104

Thank you - I missed the last line of the problem to “return the element that was removed” - reading your explanation made me realize this!


#105

Thank you all for your questions and answers to this challenge so far. This one gave me a lot of trouble and I ultimately had to look up a solution and then reverse engineer why it worked the way it did. I still have one question about the set up of this problem though. The first line reads:

function nextInLine(arr, item)

How does the code know that ‘arr’ is an array and that ‘item’ is a number? They are not defined anywhere in the code. Are these hardcoded into the Javascript? Also, how does the function KNOW to use the testArr variable that is already set up? Does it simply load it into the function because it comes immediately after the function?


#106

It doesn’t, you could do nextInLine("hello", {foo: 1}) if you wanted. The function wouldn’t work, and you’d get an error, but that’s because the logic inside the function tries to do an operation on an array: the names are arbitrary. arr in that case would be "hello" and item would be {foo: 1}; JS doesn’t care what they are, it will just blindly try to run the logic using whatever it is given. It’s just that if you do give the function an array and an item, it will work.

The function could be defined as function nextInLine(bloo, blah) {}, but arr and item are used as names because they’re more descriptive than bloo and blah.

The function knows to use testArray because it’s given testArray as an argument when it is called: nextInLine(testArr, 6) is on the second last line.


#107

Thank you for your explanation, Dan! That helps a lot. The part that really confused me was that in the solution I am expected to use arr.push(item); in the function, but .push only works with arrays (right, I think?). So I didn’t understand how it knew that arr was an array.

However (if you’ll forgive me for restating your explanation, but I just want to make sure I understand it correctly), the function doesn’t know that it is an array. Instead, it is simply waiting for an array to be passed through it. Since the console.log at the bottom of the page says to use testArr (which is an array), it is able to use the .push function on it. If we tried to send around variable through it which was not an array, it wouldn’t know what to do and would generate an error. Is my explanation of this process correct? Please feel free to let me know if I’m missing something.

I think a lot of my confusion on this exercise was not understanding that I could use modifiers like .push, .pop, and .shift directly on function parameters…


#108

got it thanks man ur explanation really helped


#109

@CoffeeBreak808 Yup, you’ve got it right.

This is, in sorta simplified form, kinda how it works is (Say you have):

var testArr = [1,2,3];

And then later, you call

nextInLine(testArr, 4);

The JS engine is going to realize it’s a function because of the parentheses (). So it’ll look up that function, and it’s going to find

nextInLine(arr, item) {
  arr.push(item);
  return arr.shift();
}

Inside the function, it’ll try to convert those to values by looking to see if the names match those of the arguments in the function definition, and if they do, assigning the values to those names - it can see one is called arr, and one is called item, so now:

nextInLine(arr, item) {
  arr.push(item);
  return arr.shift();
}

Becomes:

nextInLine(testArr, 4) {
  testArr.push(4);
  return testArr.shift();
}

testArr is a variable as well, so it will look that up, and now both the arguments are there, and the function body can be evaluated in order, top to bottom, so:

nextInLine(testArr, 4) {
  // testArr is [1,2,3]
  testArr.push(4);
  // testArr is now [1,2,3,4]
  return testArr.shift()
  // testArr is now [2,3,4], but the function is returning the
  // value testArr.shift() evaluates to, which is 1
}

push and shift modify the array they runs on, so testArr goes to [1,2,3,4] then to [2,3,4]. However, push returns the new length of the array after the item is pushed onto the end of it, and shift returns the value shifted off the front of the array. EDIT: sorry if this reads as a little bit mangled, things that have side effects (ie push does two things, modifies an array and return a different value) are generally confusing.

So inside the function, the two statements evaluate to:

4; // nothing is done with this
return 1; // but this is returned

You can pass junk in, and the engine will still try to evaluate it:

nextInLine("foo", "bar");

"foo" is assigned to arr, and "bar" is assigned to item. Inside the function, the first line is then:

"foo".push("bar");

The engine will try to convert that to a value, and will error out on that line with Exception: TypeError: arr.push is not a function- as you say, push is for arrays, but in this case it is looking for a function called push that works on strings, which doesn’t exist.

Or, if you call:

nextInLine();

With no arguments, what JS will do is try to evaluate the first line as

(undefined).push(undefined)

And that will error as well (with Exception: TypeError: arr is undefined), again, undefined is not an array, so push won’t work.


#110

This is such a great breakdown. Thank you again.

Can you tell me what happens to the 1 stored in testArr.shift if we were to call the function nextInLine again? For example, if we called:

nextInLine(testArr, 5)

and received

[3,4,5] //the new value for testArr
[2] //the new value for testArr.shift

Does that mean that the old value of 1 in testArr.shift goes somewhere else? Or is it simply overwritten and replaced by the 2?


#111

Sorry for late reply. So in this case, if you keep calling the function, it will keep modifying testArr.

So if testArr starts off as [1,2,3]:

call nextInLine(testArr, 4).
testArr is now [2,3,4], function returns 1.

call nextInLine(testArr, 5).
testArr is now [3,4,5], function returns 2.

call nextInLine(testArr, 6).
testArr is now [4,5,6], function returns 3.

call nextInLine(testArr, 7).
testArr is now [5,6,7], function returns 4.

And so on. You will overwrite the old value with the new one.


In the description, it says this is what’s called a queue, but it isn’t, not really, it’s what’s called a stack - very similar, but as per the standard description, of a stack is a data structure that holds a collection of elements: you add elements to the top of the stack, and you pop elements off the bottom. The last element in is always the one that gets dropped.

In this, push adds an element to the top of the array, shift takes one off the bottom. And in this case, it has a fixed length - as long as you use the same array, as you do here with testArr, the input array always stays the same length.

Stacks are useful for a lot of things - for example, a common coding challenge is to write a type of calculator using something called Polish Notation, but in more real life scenarios they’re used for things like backtracking when trying to figure out graph-based problems (like finding the fastest route between two points on a map).

I’m not sure of a good usecase for a fixed size stack that automatically pops when it reaches that size; often they just ovflow and error (hence the name of the website Stack Overflow).

Here is a very crude implementation of something a bit more robust:

class FixedLengthStack {
  constructor(length) {
    this.stack = [];
    this._maxLength = length;
  }
  
  // Chack what the maximum size of the stack can be.
  get maxLength() {
    return this._maxLength;
  }

  // Add an item to the stack. If by doing that, the
  // maximum size is reached, automatically pop off
  // the oldest value.
  push(item) {
    this.stack.push(item)
    if (this.stack.length > this.maxLength) return this.stack.shift();
  }

  // Pop off the oldest value if there is a value in
  // the stack.
  pop() {
    if (this.stack.length > 0) return this.stack.shift();
  }
  
  // Have a look at what the value on top of the stack is.
  peek() {
    return this.stack[this.stack.length - 1];
  }    
}
// Create a new stack with a maximum size of 4:
> const myStack = new FixedLengthStack(4);
undefined
// Start pushing values in:
> myStack.push(1)
undefined
> myStack.push(2)
undefined
> myStack.push(3)
undefined
> myStack.push(4)
undefined
> myStack.push(5)
// more elements than max, so oldest value gets popped off:
1
> myStack.push(6)
2
> myStack.peek()
6
> myStack.pop()
3
> myStack.pop()
4
> myStack.pop()
5
> myStack.pop()
6
> myStack.pop()
// Nothing left in the stack to pop:
undefined
> myStack.peek()
undefined
> myStack.push(1)
undefined
> myStack.peek()
1

#112

Hello, campers!
I do seek&destroy task and want to know can i do it without indexOf/filter method

function destroyer(arr) {
  // Remove all the values
  var args = Array.prototype.slice.call(arguments);
  for (var i = 0; i < args[0].length; i++) {
    for (var j = 1; j < args.length; j++)
     if (args[0][i] === args[j]) {
    args[0].splice(i,1);
  }
  
  }
  return  args[0];
}

destroyer([3,5,1,2], 2, 3, 5);

#113

I understood the .push and the .shift but I was completely lost on the construction of the function.
I was sure the answer was testArr.push and I had hard time understanding why it was arr.push.
Sometimes this exercises are word the wrong way or they just do it on purpose so you have to use your brain.
I’ve been searching for an explanation to this exercise and you nailed it.

Thanks