Mutations

Learn how to solve the freeCodeCamp algorithm 'Mutations' using the String.toLowerCase() & String.indexOf() methods and a good old-fashioned for-loop!

Mutations

In this freeCodeCamp algorithm we need to create a function that accepts an array with 2 words of type string that returns true if the first string in the array contains all of the letters in the second string in the array.

For example, ["hello", "Hello"], should return true because all of the letters in the second string are present in the first, ignoring case.

The arguments ["hello", "hey"] should return false because the string "hello" does not contain a "y".

Lastly, ["Alien", "line"], should return true because all of the letters in "line" are present in "Alien".

Spec

  • mutation(["hello", "hey"]) should return false
  • mutation(["hello", "Hello"]) should return true
  • mutation(["zyxwvutsrqponmlkjihgfedcba", "qrstu"]) should return true
  • mutation(["Mary", "Army"]) should return true
  • mutation(["Mary", "Aarmy"]) should return true
  • mutation(["Alien", "line"]) should return true
  • mutation(["floor", "for"]) should return true
  • mutation(["hello", "neo"]) should return false
  • mutation(["voodoo", "no"]) should return false

Psuedocode

Let's see how we can break down the requirements for this algorithm:

// Create a function that accepts an array
    
    // Create a variable for the first string in the array, lowercase it
    // Create a variable for the second string in the array, lowercase it
    
    // Create a counter variable
    
    // Loop through the second string
        // Check if current iteration in second string matches any letter in first string
        // If so, increment counter
        
    // Return boolean checking if counter is equal to length of second string

Solving the Algorithm

Setting up the function

Let's use the basic fuction boilerplate give to us from freeCodeCamp:

function mutation(arr) {
  return arr;
}

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

You'll see that our function accepts an argument arr which will be a 2-string array such as ["hello", "hey"].

Creating the variables

We need to create variables for the first and second strings within the array, string1 and string2 respectively. Then we'll create a variable named counter (or something relevant) which will be of type Number.

For the variable string1, it will be the first item within arr, so in our case that would be arr[0]. For string2 we can set it to equal arr[1].

The variable counter will be used to count how many times a letter from the first string is matched with a letter from the second string. Each time a letter is matched, we will increment counter. Once we've looped through the entire second word, we will check to see if counter is equal to the length of the second string. If so, then that means every letter in the first string is present in the second one.

Let's also make sure that we use the String.toLowerCase() method to convert string1 and string2 to all lowercase because a capital letter will not be equal to a lowercase letter.

For example:

"A" === "a" // returns false
"Hello" == "hello" // returns false
"Hello" == "Hello" // returns true

Try this the code snippet in your browser console.

function mutation(arr) {

  var string1 = arr[0].toLowerCase();
  var string2 = arr[1].toLowerCase();
  
  var counter = 0;

}
mutation(["Mary", "Aarmy"])

Looping through the strings

Since our requirement is to check to make sure every letter of string1 is present in string2, we need to setup our for-loop to iterate through the entirety of string2.

function mutation(arr) {

  var string1 = arr[0].toLowerCase();
  var string2 = arr[1].toLowerCase();
  
  var counter = 0;

  for (var i in string2) {
      // Loop through string2
  }
 
}
mutation(["Mary", "Aarmy"])

Check if letter from string1 is in string2

Within the for-loop we just created, we need to check whether or not string1 contains the letter at the current index of string2.

We can do this using the String.indexOf() method:

From MDN

The indexOf() method returns the index within the calling String object of the first occurrence of the specified value... Returns -1 if the value is not found.

Essentially if we don't get -1 from the .indexOf() method then we have a match.

Once a letter is matched, we also want to make sure that we increment counter by 1.

function mutation(arr) {

  var counter = 0;
  var string1 = arr[0].toLowerCase();
  var string2 = arr[1].toLowerCase();

  for (var i in string2) {
    
    if (string1.indexOf(string2[i]) !== -1) {
      counter++;
    }
  }
}
mutation(["Mary", "Aarmy"])

Check if counter is equal to length of string2

If counter is in fact equal to the length of string2 then we can assume that every letter in string1 is somewhere within string2.

Just like the initial spec stated, we need to "Return true if the string in the first element of the array contains all of the letters of the string in the second element of the array."

function mutation(arr) {

  var string1 = arr[0].toLowerCase();
  var string2 = arr[1].toLowerCase();
  
  var counter = 0;

  for (var i in string2) {
    
    if (string1.indexOf(string2[i]) !== -1) {
      counter ++;
    }
  }
  return counter === string2.length;
}
mutation(["Mary", "Aarmy"])

Try this the code snippet in your browser console.

Recap

We made it through the freeCodeCamp "Mutations" algorithm step-by-step by using a couple of helpful JavaScript methods: String.toLowerCase() and String.indexOf(). Hopefully you found this walkthrough helpful and if you have a solution of your own I'd love to see it!

Shoot me an email at [email protected] with any questions and if you enjoyed this, stay tuned and subscribe below! 👇

Help us improve our content