I'm reading through Eloquent Javascript and facing one of the exercises, I found a rather odd behavior. (at least for me)
the exercise asks to create a function in order to reverse an array. I thought I could loop over the array and each time pop one item from the original array and push it into a temporary array that is going to finally be returned. but as I'm looping over the array either with a for-of loop or typical sequential loop, last item is not transferred.
can someone tell me what happens exactly?
const reverseArray = function(array) {
let rev = [];
for (let x = 0; x <= array.length; x++) {
rev.push(array.pop());
console.log(rev, array)
}
return rev;
};
console.log(reverseArray(["A", "B", "C"]));
output:
["C"] ["A", "B"]
["C", "B"] ["A"]
["C", "B"]
6 Answers 6
When the pop() applies on array it decreases the length of the array so when the loop runs it finds one item less than the previous array length. Thus, what you can do is simply assign the length of the array in a variable and use that in the comparison of the for loop:
let rev = [];
const reverseArray = function(array) {
var length = array.length;
for (let x = 0; x < length; x++) {
rev.push(array.pop());
}
return rev;
};
console.log(reverseArray(["A", "B", "C"]));
1 Comment
As the pop() method remove the pop'ed item from the array, use a while loop instead of for
let rev = [];
const reverseArray = function(array) {
while (array.length > 0) { // or just "(array.length)"
rev.push(array.pop());
}
return rev;
}
console.log(reverseArray(["A", "B", "C"]));
With closure you can save yourself an extra global variable
const reverseArray = function(array) {
return (function(a_in,a_out) {
while (a_in.length > 0) { // or just "(a_in.length)"
a_out.push(a_in.pop());
}
return a_out;
})(array,[]);
}
console.log(reverseArray(["A", "B", "C"]));
Or if the Array.reverse() method is allowed
const reverseArray = function(array) {
return array.reverse();
}
console.log(reverseArray(["A", "B", "C"]));
Comments
The pop() method removes the last element of an array, and returns that element. It changes the length of an array.
const popArray = function(array) {
for (let x = 0; x <= array.length; x++) {
console.log("value of x :", x);
console.log("array.length :", array.length);
array.pop();
console.log("array after", x + 1, "pop :", array);
}
};
popArray(["A", "B", "C"]);
In the above demo we can see that everytime pop() happens on an array. array.length will decrease and value of x will be increase. Hence, At certain point of time (after 2nd iteration) value of x will be greater then the length of an array.
Use Array.from() method :
let rev = [];
const reverseArray = function(array) {
var destinationArray = Array.from(array);
for (var i in Array.from(array)) {
rev.push(array.pop());
console.log(rev, array);
}
};
reverseArray(["A", "B", "C"]);
Comments
Try using while loop instead of for loop
const reverseArray = function(array){
let rev = [];
while (array.length>0)
{
rev.push(array.pop());
}
return rev;
};
console.log(reverseArray(["A", "B", "C"]));
Comments
I put two versions for you. reverse will reverse the array without modifying the original array. reverseModify will do the same, but emptying the original array.
Choose the version that suits you better
const arr = [1, 2, 3, 4];
function reverse(array) {
let result = [];
for (let i = array.length - 1; i >= 0; i--) {
result.push(array[i]);
}
return result;
}
function reverseModify(array) {
let result = [];
while (array.length) {
result.push(array.pop());
}
return result;
}
console.log(reverse(arr), arr);
console.log(reverseModify(arr), arr);
Comments
The problem is divides into two independent operations.
iterate all elements, usually take the length and perform a loop
popa value andpush that value. This is the mechanism to take the lastitem and push it to the end of the new array.
The part for iterating needs only the actual length and a count down (by pop) to zero and then exit the loop.
For a count up, you need two vvariables, one for the counter and one for the end or length of the array, which is a static value, take from the given array, which is later mutating.
function reverseArray(array) {
var rev = [];
while (array.length) {
rev.push(array.pop());
}
return rev;
}
console.log(reverseArray(["A", "B", "C"]));
i <= array.lengththis answer will illustrate this point: obob