Sitemap
Up She Rises

musician, coder, drunken sailor

.reverse

--

So I’ve been hacking my way through the dense forest that is Free Code Camp for about 8 weeks now, all the time with this sneaking feeling in the back of my mind that I’m missing things. I don’t know much about coding, but I know enough to know that I wasn’t fully understanding what I was doing, and that I was only scratching the surface of what was really going on.

And then I found Eloquent JavaScript.

One of the coolest things EJS does is break down built-in JS functions to show you what’s really going on under the hood, as an introduction to higher-order and callback functions. This is what I was missing from my JS education. Since this revelation, I’ve been writing tutorials for built in JavaScript methods, as a way of clarifying for myself what higher order functions do and how they work. Then I was like, “hey, I have this bloggg…” and I figured I could post my ramblings in case other people have brains like mine and might find this stuff helpful.

So here you go.

string.reverse

This is probably the simplest method to wrap your head around and break down, so we’ll start there. The built-in JS method looks like this:
[code language=”javascript”]
string.reverse();
array.reverse();
[/code]
And it conveniently returns an array or string with all the elements in reverse order. But…HOW?! Let’s see if we can write a function that does the same thing:
[code language=”javascript”]
function reverse(string){
var reversedString = “ ”;
for (var i = 0 ; i < string.length ; i++){
return string[i] + reversedString;
};
return reversedString;
}
[/code]
Hey, we did it! (Well, technically I did it, but I couldn’t have done it without your emotional support.)

So what’s going on here? Well, basically, we are taking the given string as an argument, and using it’s contents to return a new, backwards version of that string.

Our for loop is iterating (looping) over each index ( [i] ) of the string, from the beginning index to string.length (the end), and it is concatenating (adding) each index to the front of the new string. “To the front” is the crux (thanks again John Hodgman) of that sentence. The loop starts at the beginning of “string” and moves from left to right, and each index is added to the beginning of “reversedString”, pushing what is already part of reversedString one index to the right (or toward the end.) Still confused? Me too. Being a visual learner sucks…let’s look closer:

Remember: JavaScript starts counting at zero, NOT one. So the first index of any given string (or array) is 0. “Index” just means the position of an element in a string. I like to think of indexes as slots for things to go in. For example, in the string “abcd”, the letter “a” is in the first position or slot. Because JavaScript starts counting at zero, we say that “a” is in the zeroth index, or [0].

at the beginning:

string = “abcd”

reversedString = “ “

first loop — string[0]:

current index value: a

concatenated to beginning of reversedString: “a”

(reversedString is empty at first, so the first letter of string will be the only thing there)

second loop — string[1]:

current index value: b

concatenated to beginning of reversedString: “ba”

third loop — string[2]:

current index value: c

concatenated to beginning of reversedString: “cba”

fourth loop — string[3]:

current index value: d

concatenated to beginning of reversedString: “dcba”

The key here is the order of concatenation specified in our for loop. If we wrote

stringReversed + string[i]

it wouldn’t work. The other key is that we are dealing with strings and concatenation, and not regular addition, as we do with numbers. Think of addition like pouring more milk into a half-full glass, and concatenation like putting popcorn on a string — the popcorn kernels don’t combine, each new kernel simply pushes whatever’s already on the string further along the string.

array.reverse

There is a way to reverse without building a new string. Let’s look at that now, but let’s use an array as our example instead of a string. Here’s the code:
[code language=”javascript”]
function reverse(array){
var temp = [];
for (var i = 0 ; i < Math.floor(array.length / 2) ; i++){
temp = array[i];
array [i] = array[array.length — 1 — i];
array[array.length — 1 — i] = temp;
};
return array;
}
[/code]
Okay, this one is a little trickier to wrap your head around. Basically, what we have to do is swap index positions.

!! Remember — in JavaScript, we start counting at 0, so the first index of an array will be array[0] NOT array[1]. Because of this, array.length will return a number that is 1 higher than the number of the last index (i.e. if an array has 4 indexes, array.length will be 4, but the value of the last array will be array[3] So, to get to the last index, we use array.length — 1:

Get Lizzie Shipton’s stories in your inbox

Join Medium for free to get updates from this writer.

Normal counting: 1 , 2 , 3 , 4 ← array.length is 4

Index 0 counting: 0 , 1 , 2 , 3 ← array.length — 1 is 3

We want to swap index[0] with the last index, then swap the second index (index[1]) with the second-to-last index, and so on. The trick here is not to overwrite variables that have already been swapped. What does that mean? Well, take this imagined code block we could have put into the for loop instead:

array[0] = array[array.length-1];

array[array.length — 1] = array[0];

At first glance, it looks like you’re replacing the value in the first index with the value in the last, and then replacing the last with the first. The problem is that by the time we get to the second line of code, the value in the first index has already been replaced with the last value. So the second line just puts the value back into its original place in the final index.

What we need is a temporary variable to hold one of the values:
[code language=”javascript”]
var temp = array[0];
array[0] = array[array.length — 1];
array[array.length — 1] = temp;
[/code]
Here, the first index value is safely stored in the temp variable, while the last index value is swapped into the first index. Then we grab the first index value — untouched — from the temp variable. Imagine this scenario: you and your friend Amber want to swap jackets, but you’re both already wearing the jackets. You can’t just put Amber’s jacket on over yours because then how would you take yours off to give to her? You need a third friend — Jessica — to hold onto your jacket while you put on Amber’s jacket — then Amber can take your jacket from Jessica.

Okay, so now we can swap our index values. Unfortunately, the entire reverse process is slightly more complicated in that we need to swap the values at the second and second-to-last indexes, third and third-to-last indexes, etc. Instead of simply swapping array[0] with array[array.length — 1], we need to change which indexes are being swapped each time the loop starts. This is where array[i] comes in. As i increments in our for loop, it will also increment inside the brackets, so with each iteration we will move from the first index along the array until i stops incrementing. At the same time, we also want to move further away from the end of the array with each iteration. array[array.length — 1] is the last index of our array, so if we simply decrement i from that value every time, we will move one index backwards on each iteration, starting at the last index:

when i = 0

the first index to be swapped is array[0] (the first index)

the second index to be swapped is array[array.length — 1–0] or array[array.length — 1] (the last index)

when i = 1

the first index to be swapped is array[1] (the second index)

the second index to be swapped is array[array.length — 1–1] or array[array.length — 2] (the second-to-last index)

when i = 2

the first index to be swapped is array[2]

the second index to be swapped is array[array.length — 1–2] or array[array.length — 3]

and so on and so on….

The final issue we need to take care of is when to stop our loop. If you’re savvy, you may have already realized the dilemma we’re about to come up against: if we loop over the entire array, once we cross the halfway point we will be undoing everything we did in the first half. If our array is 4 indexes long, we will swap the first and second indexes with the fourth and third indexes on the first two iterations of our loop. Done! If we continue swapping down the entire length of the array, we’ll just be swapping those values back into their original positions. How do we solve this?

Duh! Only iterate over half of the array (array.length / 2)

But what if the array has an odd number of indexes?

In the case of an odd-numbered array, we don’t need to do anything to the middle value — it will be the same backwards as forwards:

1 2 3 4 5

5 4 3 2 1

If we were to divide the length of this array by two, we would get 5/2 = 2.5. Unfortunately, we can’t tell JavaScript to iterate over the 2.5 index of an array. Well, we could, but it would probably end in tears. Fortunately, here we can use a clever bit of built-in JS functionality (I know I know! The whole point of this is to break down built-in functionality. But I haven’t gotten around to breaking down this particular function yet…because i think it’s probably really hard and I’m just a newb after all….)

Math.floor rounds down whatever argument it is given (whatever is in the parentheses that follow it) to the nearest whole number. In this case, we are rounding 2.5 down to 2. This stops our for loop after only 2 iterations, saving us from overwriting all our hard work:

Math.floor(array.length / 2)

If our array is even-lengthed, rounding down will simply output the same number it would have without rounding (4/2 = 2 and 2 rounded down is…2!)

<

p class=”p1">And that’s it! Let’s put all the pieces together:
[code language=”javascript”]
function reverse(array){
//declare the function (we won’t get very far without that…)
var temp = [];
//temporary variable holds our jacket (index value)
//it must be declared OUTSIDE the for loop….can you see why?
for (var i = 0 ; i < Math.floor(array.length / 2) ; i++){
//set up our for loop to iterate over only half of the array,
//by dividing the length in half (rounded down for odd-length arrays)
//perform the following action for each index
temp = array[i]; //get the value of each consecutive index
array [i] = array[array.length — 1 — i]; //swap the values
array[array.length — 1 — i] = temp; //replace the last, second-to-last, etc.
};
return array;
}
[/code]
So that’s the under-the-hood functionality of the .reverse method. Of course, there are many other ways to accomplish these tasks — if you know of any that are better, please let me know in the comments!

Until next time:

Thanks, and happy whatever-you-do.

--

--