Bonfire: Mutations Solution

Mutations

I’m getting excited because after this Mutations Bonfire, there will only be three left to go through before we hit the Intermediate Bonfire challenges! Free Code Camp has also been growing and adding to their learning map and we might be seeing some more coding challenges coming out of it. For now, though, let’s get over Mutations and see where these Beginner’s Bonfires take us next.

Here’s what the Bonfire starts us off with:

function mutation(arr) {
  return arr;
}

mutation(["hello", "hey"]);

No message of encouragement? That’s OK, the Bonfire wants us to test the two strings fed into mutation() to see if they contain the same letters regardless of what order the letters are in (for example, “orange” and “range” should return true, whereas “puppy” and “carton” would return false). Bonfire wants us to test the letters only, so we should assume that if there were capitals letters involved in one string but not in the other, it should still return true (for example, “Olive” and “olive” should still return true).

There’s going to be a little bit more code put into this one than the Slasher Flick Bonfire, so let’s get on with it by doing an approach.

Approaching the Problem

  1. Like we’ve seen in Bonfires past, whenever we have to deal with comparing one string to another where title or lower case doesn’t matter, we should endeavor to strip the strings of capitals as one of the first steps.
  2. What we’re going to need to do after stripping the strings of uppercase characters is compare them in some way. An if statement nested inside of a for loop will allow us to test all the characters and evaluate for truth or falsehood. We can use indexOf() and charAt() to accomplish this. If I remember right, prior to Free Code Camp switching to their own Javascript lessons, we dealt briefly with indexOf() and charAt() with Code Academy.

Setting Up For the Mutations Solution

The first thing I’m going to do, like I stated in my approach is force the strings to become lowercase to take that variable out of the equation and make evaluating the two strings much easier. We do that by using the toLowerCase() method. We’ve seen toLowerCase() before in the Title Case a Sentence Solution and the Check for Palindromes Solution. It essentially takes in a string and forces all characters to become lowercase. Fairly straightforward. We’re going to call toLowerCase() here and apply it to both of the arrays that mutation() took in as arguments.

function mutation(arr) {
var firstString = arr[0].toLowerCase();
 var secondString = arr[1].toLowerCase();
return arr;
}
mutation(["hello", "hey"]);

In the above code, I’ve taken the first value in arr and the second value in arr and forced them both to be lowercase using toLowerCase(). Since mutation() was feeding us an array with two values in it, I had to reference arr, plus whichever array position contained the value I needed to manipulate. This should give us two lowercase strings to work with.

Next up, we’re going to need to write a for loop that will iterate through the first or second string and compare it to the other. So let’s write that now:

function mutation(arr) {
var firstString = arr[0].toLowerCase();
 var secondString = arr[1].toLowerCase();
for (var i = 0; i < secondString.length; i++) {
}
return arr;
}
mutation(["hello", "hey"]);

In the above code, I’ve added a simple for loop that will iterate through all the characters (or the total length) of secondString. Inside of this for loop, we’re going to run an if statement using indexOf() and charAt() to compare the characters of firstString to secondString and see if they match up. The reason why we’re running the for loop on secondString is so we can evaluate true for instances where firstString might have a value of “alien” and secondString might have a value of “line”. If we wrote the for loop for firstString, it will evaluate to determine if “line” has all the characters of “alien” instead of the other way around. This will cause Bonfire to reject your solution, so use secondString to loop and check firstString against.

Let’s Talk indexOf()

Before we get to the solution from here, let’s take a brief journey down the magical path of array methods. Most notably the two we’re going to use to evaluate firstString and secondString. Let’s start with indexOf().

indexOf() is an array method that’s used to return a number that specifies the place of the first instance of a string within an array. I know how sloppily put together that sentence is so here’s an example that should demonstrate how indexOf() works a little more clearly:

var endWorld = "What the caterpillar calls the end of the world the master calls a butterfly.";
 var word = endWorld.indexOf("master");
console.log(word);

In the above code, you should log out the number 52, which is the start of the word “master”. It should be noted that both indexOf() and charAt() consider spaces as a part of the index of a string, and in case you haven’t guessed by now, 0 is the first position.

So, we’ll use this method in our solution on firstString to tell it to go through each of the characters in its array and evaluate it against secondString. Another very useful thing about indexOf() is you don’t need to search full words, you can search partial words or single characters. Like this:

var love = "Love is metaphysical gravity.";
 var letter = love.indexOf("t");
console.log(letter);

The above should return 10 for the first t that appears in ‘metaphysical’. Now, indexOf() can also return a -1. When it does that, it means that there was a hiccup somewhere, or indexOf() simply didn’t find a match for what was searched. Let’s take a look at charAt() now.

Taking a Look at charAt()

charAt() is a little similar to indexOf(), except instead of returning the number where a character or string occurs, it returns the character when we feed it a number. Here’s an example of charAt() in action:

var words = "A thousand words will not leave so deep an impression as one deed.";
var deeds = words.charAt(11);
console.log(deeds);

The above will log out ‘w’ because that’s the character at position or index value 11. charAt() is going to be useful for us as we use it to return a character at a specific number while looping through and checking secondString against firstString.

The Mutations Solution

OK, now that we have those two methods down. Let’s work out our solution. The first thing we need to do is ensure that we can check firstString using an if statement and iterate through all of its characters. We’re going to use indexOf() and feed it the value of i, because i is what we’re using to loop through secondString. This ensures that we work through the entirety of firstString and check each and every character in it:

function mutation(arr) {
var firstString = arr[0].toLowerCase();
var secondString = arr[1].toLowerCase();
for (var i = 0; i < secondString.length; i++) {
if (firstString.indexOf(i) == -1) {
return false;
}
}
return true;
}
mutation (["hello", "hey"]);

What we’re building up there is a framework for checking firstString. I’ve got a placeholder variable of i in the indexOf() right now, so if you ran this, it won’t evaluate properly in the Bonfire and will likely return false. But what we’re doing is putting firstString through an if statement. We’re evaluating each of its characters as we iterate through firstString using the variable i, which is set to the length of secondString. We have an equals to operator that checks to see if at any point indexOf() returns -1, if it does then false is sent to mutation(), if indexOf() never returns -1, then true is sent to mutation(). Let’s finish this now by adding in the check for charAt() with secondString:

function mutation(arr) {
var firstString = arr[0].toLowerCase();
var secondString = arr[1].toLowerCase();
for (var i = 0; i < secondString.length; i++) {
if (firstString.indexOf(secondString.charAt(i)) == -1) {
return false;
}
}
return true;
}
mutation (["hello", "hey"]);

And there we have it. What we added was secondString.charAt(i) which iterates through secondString’s characters using i which is set to secondString’s length. If at anypoint indexOf() returns a -1 (which means it can’t find a character in secondString that equals a character in firstString, we get false. If it never gets -1, we return true. Run it and it will evaluate. Yay! We solved the Mutation problem.

It’s been a while since I’ve had to dig this deeply into any kind of code, and I have nothing even remotely close to a formal education in Computer Science Theory, but my impression of mutations in programming was that it has to do with changing something to something else during runtime. As a side effect of this, mutation also deals with the concept of the order in which operations are done as very often in your code, you might be looking back at what something used to be before it was “mutated”.

The fact that this Bonfire is called Mutations makes me think they’re trying to get something across about how this order of operations business is going to go down. And if I’m not mistaken, this isn’t really the first time we’ve dealt with mutations, it’s only the first time the Bonfires called it for what it is. If you want to read up more about mutations, there’s an excellent paper here about it. Not specifically geared toward Javascript, but still useful regardless of what programming language you’re dealing with.

Resources

MDN, charAt()
A description of charAt(), what it does and a ton of examples about how to use it.

MDN, indexOf()
A page about indexOf() on the MDN. Describes what it does and includes lots of examples.

Wulkan.me Mutations Solution
Wulkan has a different approach to the solution for this Bonfire. His solution trims out the usage of charAt().


10 comments on “Bonfire: Mutations Solution

  1. Jesus Hernandez on

    Hello, your explanations and break down of each bonfire are very helpful for me! I like how you explained the charAt() and IndexOf()–and provided examples of each!…very helpful.

    Reply
    • Khanh on

      Hi, Harpreet. Thanks for dropping by and leaving a comment. To be honest, it takes me a long time to solve these challenges, though I’m a little faster now than I was when I first started. I’m a UI/UX and graphic designer first. I’m so much more comfortable with design than I am working with code like this. These challenges are great though because they really force me to switch gears and they help with problem solving. 🙂

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.