Basic Algorithm Scripting: Mutations - where to start

Tell us what’s happening:
I have no idea where to start with this exercise. Can anyone offer any ideas?

Your code so far


function mutation(arr) {
const newArr = arr.map(item => item.toLowerCase());
console.log(arr);
return newArr;
}

mutation(["Hello", "Hey"]);

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36.

Challenge: Mutations

Link to the challenge:

I tried the following code. It passed all the tests for true but none for false.

function mutation(arr) {
  let word1 = arr[0].toLowerCase();
  let word2 = arr[1].toLowerCase();
  word1 = word1.split('');
  word2 = word2.split('');
  for (let i = 0; i < word2.length; i++) {
    for (let j = 0; j < word1.length; j++) {
      if (word2.indexOf(i) === word1.indexOf(j)) {
        return true;
      } else {
        return false;
      }
    } 
  } 
}

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

Let’s break down what’s happending on this line word2.indexOf(i) === word1.indexOf(j) on the first loop through assuming an input of ['hello', 'hey'].

// word1 = ['h', 'e', 'l', 'l', 'o']
// word2 = ['h', 'e', 'y']
// i = 0, j = 0
word2.indexOf(i) === word1.indexOf(j)

// plug in the values
['h', 'e', 'y'].indexOf(0) === ['h', 'e', 'l', 'l', 'o'].indexOf(0)

// The value 0 is not equal to 'h', 'e', or 'y' so indexOf returns -1
-1 === ['h', 'e', 'l', 'l', 'o'].indexOf(0)

// The value 0 is not equal to 'h', 'e', 'l', or 'o', so indexOf returns -1
-1 === -1

// The left and right are strictly equal so the comparison evaluates to
true

So your function returns true for every test input immediately at the start of the first loop. You likely want to be using the index i to be looking at a single character of word2, like this let character = word2[i].

Hi. Return will stop the function at the first coincidence.

I suggest using this method to determine if a string contains a character: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes

It returns a boolean just like you need to do for this challenge, so it should come in handy.

const word = 'hello';
word.includes('h') // true
word.includes('e') // true
word.includes('y') // false

ok, thank you, I see what you mean.

Yes, I see. Thanks for the MDN link.

The includes method does seem very appropriate here. I’ll see what I can do with that.

thanks again

Below is my latest code. It passes everything but mutation([“hello”, “hey”]). I’m not sure if that’s random chance, or if my code is anywhere near correct.

function mutation(arr) {
  let word1 = arr[0].toLowerCase();
  let word2 = arr[1].toLowerCase();
  word2 = word2.split('');
  for (let i = 0; i < word2.length; i++) {
    if (word1.includes(word2[i])) {
      return true;
    } else {
      return false;
    }
  }
}

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

You’re issue is in the placement of return true. Like I did above let’s break down what happens at the if statement on the first loop through.

word1.includes(word2[i]))

// plug in values
'hello'.includes(['h', 'e', 'y'][0])

// evaluate it
'hello'.includes('h') // => true

And because that evaluates to true, the if statement immediately returns true. The issue is that you haven’t even checked ‘e’ or ‘y’ yet.

Basically, inside the loop you should immediately return false whenever a character from word2 is not found in word1. Otherwise, complete the loop and then return true after checking every character in word2.

I think I understand why my code doesn’t work but I’m not sure I understand your explanation on what to change.

Here’s my updated code, which doesn’t work either, but I’m trying to figure out what you mean by “inside the loop you should immediately return false whenever a character from word2 is not found in word1. Otherwise, complete the loop and then return true after checking every character in word2.”

function mutation(arr) {
  let word1 = arr[0].toLowerCase();
  let word2 = arr[1].toLowerCase();
  word2 = word2.split('');
  for (let i = 0; i < word2.length;) {
    if (word1.includes(word2[i])) {
      i++;
      return false;
    } else {
      return true;
    }
  }
}

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

Sorry, I’m not understanding. Still not clear on what’s wrong or how to fix it. Here’s another version:

function mutation(arr) {
  let word1 = arr[0].toLowerCase();
  let word2 = arr[1].toLowerCase();
  word2 = word2.split('');
  for (let i = 0; i < word2.length; i++) {
    if (word1.includes(word2[i]) != true) {
    }  {
      return false;
    } {
      return true;
    }
  }
}

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

ok, thanks for the confirmation.

Can you please clarify “see if you can figure out when you return true (which is what your code is doing).”

Are you asking me to look at when the code will return true, or when it should return true? Or where in the code I should return true? And can you please explain what you mean by “(which is what your code is doing)” - what is it doing?

I’m sorry, I don’t understand what you mean by “go line by line with the test case and note what the values are and see when the return gets executed”

which values am I checking? Which return are we talking about - true or false? Both? I tried console.log(word1) and console.log(word2) but that just tells me the values assigned to those variables.

Like this (using your second rendition):

function mutation(arr) {
  let word1 = arr[0].toLowerCase();
  let word2 = arr[1].toLowerCase();
  word2 = word2.split('');
  console.log('word1: ' + word1, 'word2: ' + word2);
  for (let i = 0; i < word2.length; i++) {
    console.log('i: ' + i, 'character: ' + word2[i]);
    if (word1.includes(word2[i])) {
      console.log(word2[i] + ' found in ' + word1);
      console.log('exiting function returning true');
      return true;
    } else {
      console.log(word2[i] + ' not found in ' + word1);
      console.log('exiting function returning false');
      return false;
    }
  }
}
1 Like

@colinthornton. I inserted the console.log statements into the code as you suggested. However I am not sure why I need to do this or what I am looking for.

This is what it logs to the console:

word1: hello word2: h,e,y
i: 0 character: h
exiting function returning false

Whatever it is, it’s a mystery to me…

Based on that logging, there a couple things that spring up in my mind.

  • the character ‘h’ is found in ‘hello’, but it returns false
  • word2 also contains the characters ‘e’, and ‘y’, but those aren’t being checked (because the function returns on the first iteration)

So that says my code is incorrect, which I already know. Unfortunately it does not help me conceptualize what needs to be changed or fixed.

I do understand (I think) that I need to iterate through all the items in word2 to check to see if they exist in word one. The moment a character in word2 does not show up in word1, then I can return false, right? In the event all the characters in word2 are in word1, then I can return true, right? Am I right with my conceptualization?

1 Like

Thanks for confirming.

OK, I have understood that for a while now, but I am still stuck. Maybe I am not understanding how the includes method works. It know it checks one array against a value and returns a boolean if the value is in the array, right?