FCC ‘Seek and Destroy’

This post will work through ‘Seek and Destroy’, one of freeCodeCamp‘s basic algorithm scripting challenges.  This challenge will help us introduce the Arguments object and callback functions.

The Seek and Destroy challenge states that ‘provided with an initial array (the first argument in the destroyer function), followed by one or more arguments’ we need to write a function that will remove the values of all the arguments given after the initial array, from the initial array.

Sounds confusing, I know…  Let’s visualize it to clear things up.

 

One of the major problems we have lies with ‘followed by one or more arguments’…  If we don’t know how many arguments there will be, how do we write a function to handle them?

The answer to that comes in the form of the Arguments object.  JavaScript provides a local variable ‘arguments’ that acts like an array with an element for each argument passed to the function.  You access the arguments just like you would an element of any other array like so:

The arguments object makes solving this algorithm challenge much easier.  Looking forward at ways to solve this problem, we need to a) access the arguments we need to delete from the initial array and b) somehow remove those arguments from the array.

Storing arguments for easy access

The first thing we’ll do is create a new array and store all the arguments (other than the initial array) in it.

As you can see, arguments can be treated like any other array…  Here, we used the length property and looped through arguments (starting at element 1 so as to avoid the initial array, which will be passed in as the first argument, or arguments[0]).  Setting it up this way will handle any number of arguments passed to the destroyer function.

The push() method in JavaScript is used to ‘push’ new elements on to the end of the calling array.

Tools we’ll need to remove arguments from the array

In order to remove the arguments from the initial array, we will use the filter() method.  The filter method introduces a concept we haven’t talked about here at CrookedCode: the callback function.

A Quick note on functions in JavaScript

The power of functions, and what they allow you to do, are core to successful JavaScript programming.  Functions can be passed to and returned from other functions.  They can also be stored as variables.

A function that accepts another function as an argument is called a higher-order function, whereas, the function that is passed as the argument is called a callback function.  The Eloquent JavaScript chapter on functions is a great tutorial on the use of functions in JavaScript.

Eloquent JavaScript also devotes an entire chapter to higher-order functions.  I highly recommend reading and working through the examples in both of these chapters.  If you’re looking for something a little quicker, JavaScriptissexy.com has an excellent article on understanding callbacks and higher order functions.

The filter() method accepts a callback function and performs that callback on every element in the calling array.  If the callback returns true for a given element, that element is kept.  If the callback returns false, obviously, that element is not kept.

As stated above, filter() calls the callback function on every element of the calling array, but it does not mutate that array.  Therefore, you must save the kept elements as a new array.

The one final tool we’ll need before we try to solve this algorithm is the array.indexOf() method.  indexOf() will return the first index at which a given value is found.  If the given value is not found, indexOf() returns -1.

Putting it all together…. (finally)

We’ve already created argArr[] to hold the values that we need to delete from the initial array.  We now need to write a callback function for filter() that will return true if we want the element to stay and false if we want to delete that element.

We know that indexOf() will return -1 if a given value is not found.  We also know that we want to keep elements of the initial array that aren’t found in argArr[].  So, for each element of the initial array, lets call argArr.indexOf(), and return true for values of -1.  Therefore, we’ll be returning true for (and keeping) values that aren’t in argArr[].

Like so:

Wow…  This post covered a bunch of stuff we haven’t previously gone over here at CrookedCode, hopefully this helped straighten out the code for you.  See you next time…

-Jeremy

FCC ‘Title Case A Sentence’

Today we’re going to work through another of freeCodeCamp’s Basic Algorithm Scripting challenges – ‘Title Case A Sentence’.  To solve this challenge we must write a function that accepts a string, then returns that string with the first letter of each word capitalized and the remainder of each word in lowercase.

We’ll be using concepts that we’ve covered in previous posts (i.e. for loops, string methods, and arrays) and adding a couple new things like method chaining and some new string methods.

As I’ve mentioned previously, in JavaScript, the data type String has many methods associated with it.  W3schools has a good intro to these methods, MDN covers the string object on a deeper level.

Here’s the starting point given to us by freeCodeCamp.

We’ll start solving this challenge by breaking the given string (str) into an array of words, the same way we started ‘Find the Longest Word in a String’.

Quick tangent – we haven’t discussed yet that JavaScript can be tested right in your browser.  If you have a question about what a snippet of code does, just plug it into the console of your browser and test it.   To make sure the str.split() method that I just created is doing what I want, I plugged it into the console in Chrome and tested it.

As you can see, str.split(‘ ‘) is splitting the given string into an array, with each word as an individual element.  Now I’m confident in continuing with the solution to the algorithm challenge…

Next, we need to iterate through the array and capitalize the first letter of each word and lowercase the rest of the word.  To iterate through the array, we’ll use a for loop.  To handle the upper/lowercasing of the words, we’ll need a couple new string methods.

For a deeper understanding, and a list of many more string methods, check out the MDN page on strings.  Today, we’ll be using charAt(), toUpperCase(), toLowerCase() and slice().

toUpperCase() and toLowerCase() do exactly what they sound like, they return the calling string value in upper and lower cases respectively.  charAt() allows you to access a specific character of a string and takes one parameter – the index of the character you want to access (indexes of strings start at 0, just like arrays).

slice() allows you to access a specific segment of a string.  It takes two arguments, the indexes of where you want the segment to start and finish.  The second parameter is optional, if you leave it out, the slice will start at the first index you provide and continue to the end of the string.  Very important – all four methods mentioned above return the value of a string, they do not change the calling string.  See code below for demonstration…

Now, as mentioned above, we can chain these methods together using dot notation, so that after one method is called, a second method is called on the returned string of the first.

Check out this post on method chaining for a better understanding.

We can use everything we’ve talked about to get the first character of a string and capitalize it, then get the rest of the string (starting at index 1) and lowercase it.  Putting it all together looks like this:

Several notes on the above solution…

We used the join() method, which does the exact opposite of split.  join() is an array method that returns a string delimited by what you pass as an argument.  In this case, we gave an empty space (” “) as the argument, so each element of the array was joined together separated by a space.

Also, you will note that we used a ‘+’ to connect 2 parts of a string together.  This is an easy way in JavaScript to build a string.  It can be used with both literal strings and variables as such:

Hopefully this straightened out the code for you…  See you next time.

-Jeremy