Just me again... I can't figure out where I went wrong with Whale Talk

Hi again,

Sorry to keep posting - I’m hoping I’ll get the hang of this soon!

So, I’ve completed all the instructions in Whale Talk and checked the accompanying video to see if I was coding correctly - it appears to me to be the same. However, my code is returning ‘A’, ‘I’, ‘O’ twice (when they should only be returned once, and the ‘E’ and ‘U’ thrice, when then they should be returned only twice. I have no idea why!!

let input = 'Hi, human';
const vowels = ['a', 'e', 'i', 'o', 'u'];
let resultArray = [];

for (let i = 0; i < input.length; i++) {
  for (let j = 0; j < vowels.length; j++) {
    console.log(j);
    if (input[i] === vowels[j]) {
      if(input[i] === 'e'){
        resultArray.push('ee');
      } else{
        resultArray.push(input[i]);
      }
      if (input[i] === 'u'){
      resultArray.push('uu');
    } else{
      resultArray.push(input[i]);
    }
    }


    }
  }
  console.log(resultArray.join('').toUpperCase());

2 Likes

In your example with let input = "Hi, human', think about what happens when your logic reaches the second character of input, which is i:

  • The first if (input[i] === vowels[j]) will be true because i is also in the vowels array.
    • Inside that if, it will check if(input[i] === 'e'). This fails. It goes to your else statement and does resultArray.push(input[i]);
    • The code is still inside the first if. Next we find another if: if (input[i] === 'u'). This also fails because input[i] is i. It goes to your else statement and does: resultArray.push(input[i]);

See what’s happening? Your else statements are duplicating the letters pushed to resultArray.

Similarly, in the case of e or u, one of the if statements will be true and double the ee or uu, but the other if statement will fail and its else will again push to resultArray.

The takeaway is: just because an if statement checks true it doesn’t finish the loop. All the code inside the loop will be executed unless you use special loop keywords to alter it. So keep that in mind when you are thinking about your solution

3 Likes

@irlfede Thank you! I played around with the code and it’s working now but I don’t think I did it properly. Because I pushed an ‘ee’ and then a ‘u’ which means it is returning correctly, but not for the right reasons. I also removed the second else for the ‘u’ because I realised that was duplicating the code… I think?!

let input = 'turpentine and turtles';
const vowels = ['a', 'e', 'i', 'o', 'u'];
let resultArray = [];

for (let i = 0; i < input.length; i++) {
  for (let j = 0; j < vowels.length; j++) {
    console.log(j);
    if (input[i] === vowels[j]) {
      if(input[i] === 'e'){
        resultArray.push('ee');
      } else{
  
        resultArray.push(input[i]);
      }
      if (input[i] === 'u'){
      resultArray.push('u');
    } 
    }
    }


    }

  console.log(resultArray.join('').toUpperCase());

  1. If you only care about using E and U, what’s the point of parsing through the vowels array every time? Instead, travel through the input string with one for loop and use if statements to check if the letter matches your criteria.
  2. The way you are pushing to resultArray, the rest of the input is lost. I think the exercise wants you to keep the entire message, while duplicating certain letters.
  3. You are only pushing a single u because after if (input[i] === 'u') you are only pushing one with resultArray.push('u'); instead of .push('uu')

Try to write down the steps of the logic you need. This will help you with your code.

// 1 travel through the input string

// ...your code

// 2 check IF the letter in the input string matches 'e'
//   2.1 if it does, push 'ee' 

// ... your code

// 3 check IF the letter in the input string matches 'u'
//   3.2 if it does, push 'uu'

//  ... your code

// 4 push the current letter to the resultArray

// ... your code
1 Like

@irlfede Thanks again for your reply.

I’m pushing a single u because when I push uu it returns uuu. With the single u it returns and logs `uu’. I really don’t know why! Hence why I said it was working but for the wrong reasons. But I’m playing around with it again now! :slight_smile:

So I went back to the instructions and realised I was nesting the .push('ee') in the inner loop and that’s why it was executing incorrectly. So now I’ve placed it in the outer loop.

I’ve spent an two more hours on this but now nothing is logging at all on the console. Please, can anyone spot where I’ve gone wrong.

let input = 'turpentine and turtles';
const vowels = ['a', 'e', 'i', 'o', 'u'];
let resultArray = [];

for (let i = 0; i < input.length; i++)//outer loop 
{
  for (let j = 0; j < vowels.length; i++)//inner loop 
  if (input[i] === vowels[j]); {
    resultArray.push(input[i]);
  } 
  //inner loop ends
if (input[i] === 'e') {
  resultArray.push('ee'); 
  } if (input [i] === 'u'){
  result.Array.push('uu');
} else {
  resultArray.push(input[i]);
}
}
console.log(resultArray);




    



This (at least when I run it off platform) says that I’ve reached the maximum stack heap-which basically means it’s taking too much time/memory. First, look to see if there are any {s associated with the inner loop.

This is an infinite loop. It repeats while j < vowels.length, but j is never incremented.

3 Likes

I created an infinite loop. Thanks @midlindner!

There is actually nothing wrong with your output here. This code follows the instructions pretty much exactly as I recall. It could stand having the indentation cleaned up a bit:

let input = 'turpentine and turtles';
const vowels = ['a', 'e', 'i', 'o', 'u'];
let resultArray = [];

for (let i = 0; i < input.length; i++) {
  for (let j = 0; j < vowels.length; j++) {
    console.log(j);
    if (input[i] === vowels[j]) {
      if(input[i] === 'e') {
        resultArray.push('ee');
      } else {
        resultArray.push(input[i]);
      }
      if (input[i] === 'u') {
        resultArray.push('u');
      } 
    }
  }
}

console.log(resultArray.join('').toUpperCase());

It is a little inconsistent with how you handle e’s and u’s, but it works.

@midlindner I placed the follwoing code in the inner loop when it should have been in the outer one.

[quote="vickyrai, post:3, topic:561210"]

if(input[i] === ‘e’){
resultArray.push(‘ee’);
} else{

    resultArray.push(input[i]);
[/quote]

No. It needs to be in the inner loop. You could get rid of the else, and perform the steps in this order inside your inner for loop:

  1. If the letter is a vowel, push it to the result array.
  2. If the letter is ‘e’ push ‘e’ to the result array. (now you have two e’s)
  3. If the letter is ‘u’ push ‘u’ to the result array. (now you have two u’s)

That’s all you need.

I see what you’re saying but the instructions are as follows:

Note, this statement belongs after the inner for loop block inside the outer for loop. This is because you only want to perform this check once for every letter in the input .

There are many ways to accomplish the end result. Here is your code modified just a bit:

Whale Talk
let input = 'turpentine and turtles';
const vowels = ['a', 'e', 'i', 'o', 'u'];
let resultArray = [];

for (let i = 0; i < input.length; i++) {
  for (let j = 0; j < vowels.length; j++) {
    if (input[i] === vowels[j]) {
      resultArray.push(input[i]); // or resultArray.push(vowels[j]);
      if (input[i] === 'e' || input[i] === 'u') {
        resultArray.push(input[i]);
      }
    }
  }
}

console.log(resultArray.join('').toUpperCase());

Output:

UUEEIEEAUUEE

Edit:

Placing the code you specified outside the inner for loop works as well:

Whale Talk
let input = 'turpentine and turtles';
const vowels = ['a', 'e', 'i', 'o', 'u'];
let resultArray = [];

for (let i = 0; i < input.length; i++) {
  for (let j = 0; j < vowels.length; j++) {
    if (input[i] === vowels[j]) {
      resultArray.push(input[i]); // or resultArray.push(vowels[j]);
    }
  }
  if (input[i] === 'e' || input[i] === 'u') {
  resultArray.push(input[i]);
  }
}

console.log(resultArray.join('').toUpperCase());

Output:

UUEEIEEAUUEE

1 Like

Thank you for that @midlindner. However, even after editing my code to be exactly like the second example you’ve provided, it’s coming up with an error message about an unexpected token ). I’m calling it a night on that exercise and I’ll try in again in the morning :slight_smile:

2 Likes

The error message includes information that should make it pretty easy to find an unexpected ). If you have trouble sorting it out, post your code along with the error message when you have the time.

1 Like

So this is the error message:

/home/ccuser/workspace/learn-javascript-loops-P1/main.js:23
});
^
SyntaxError: Unexpected token )
at createScript (vm.js:53:10)
at Object.runInThisContext (vm.js:95:10)
at Module._compile (module.js:543:28)
at Object.Module._extensions…js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)Preformatted text
at Function.Module._load (module.js:439:3)
at Module.runMain (module.js:605:10)
at run (bootstrap_node.js:427:7)
at startup (bootstrap_node.js:151:9)

For the following code:

let input = 'turpentine and turtles';
const vowels = ['a', 'e', 'i', 'o', 'u'];
let resultArray = [];

for (let i = 0; i < input.length; i++) {
  for (let j = 0; j < vowels.length; j++) { 
  if (input[i] === vowels[j]) {
    resultArray.push(input[i]);
    }  
  }
if (input[i] === 'e' || input [i] === 'u') {
  resultArray.push(input[i]);
} 
console.log(resultArray.join('').toUpperCase());




    



You are missing a curly bracket } to close your for loop. Add one right before your final console.log

1 Like

Genius :smile: Thank you! It’s finally working properly now! And for the right reasons!!

Sorry if I’m being a bit dumb here, with your first Whale Talk, which part of the code doubles the ‘e’ and ‘u’?
Is it just because of the second for loop?