2

const stringConvert = string => {
  let splitString = string.split("");
  let vowels = splitString.filter(letters => {
    return letters === "a", "e", "i", "o", "u"
  })
  return console.log(vowels);
};


stringConvert("Why don't you try and split this string into vowels, please?");

The code above comes back undefined and I am trying to create a function that takes a string and counts how many vowels are in it. So far I have used the .split() to create an array with each individual character of the string and then I tried using .filter() to filter out each character that is a vowel.

What (only vanilla javascript) would allow me to filter out each vowel from an array, so then I could use .length on that array to get the number of vowels?

0stone0
  • 34,288
  • 4
  • 39
  • 64
  • 1
    you are returning the result from console.log which is undefined. Why not return `vowels` instead? – Lee Taylor Apr 14 '22 at 14:36
  • 5
    That's not how you compare to multiple values. Your `return` statement is equivalent to `return (letters === "a"), "e", "i", "o", "u"`. And due to the way the comma operator works, that's equivalent to `return "u";` Use `return ["a", "e", "i", "o", "u"].includes(letters);` – Barmar Apr 14 '22 at 14:38
  • 1
    Also, `console.log()` just prints its argument, it doesn't return it. That's why the function returns `undefined`. – Barmar Apr 14 '22 at 14:40
  • I've removed the remote link and placed your code in a snippet so we can 'run' it without leaving SO. This creates a [mre] that makes a question easier to answer. If you have any other questions about asking here on SO, consider reading [ask] and [tour]. – 0stone0 Apr 14 '22 at 14:41
  • @Barmar I have done that and it doesn't do anything at all. Could you complete that in jsbin and send it in the comments? –  Apr 14 '22 at 14:47
  • 1
    Working example: https://jsfiddle.net/barmar/8yLrcg15/1/ – Barmar Apr 14 '22 at 14:50
  • `[...string].filter(letter => 'aeiou'.includes(letter.toLowerCase())).length` Is probably what you want. – Wyck Apr 14 '22 at 14:56
  • @Barmar wow thanks man! I'm quite new to JS so could you please explain to me how include() does this? From my research include() only returns a boolean, while filter() actually filters the elements based on the condition, so why do I need include()? Thanks –  Apr 14 '22 at 14:57
  • 2
    `filter()` filters based on a boolean, and `includes()` returns that boolean. It sounds like you didn't see that `includes()` is being used in the condition. – Barmar Apr 14 '22 at 14:57
  • 1
    I'm voting to reopen because although the duplicate shows one approach, it's not the only way -- especially when dealing with strings and upper/lowercase. – Wyck Apr 14 '22 at 15:01
  • @Barmar I thought the `return` itself would return the result of `filter()` to the function, returning all the vowels to the variable. So you have to use `.include()` also? –  Apr 14 '22 at 15:06
  • My use of `return ...includes()` is in the exact same place as your `return letters === "a", "e", "i", "o", "u"` and serves the same purpose. I'm not sure what's confusing you about what gets returned. – Barmar Apr 14 '22 at 15:08
  • @Barmar `includes()` : Check if an array contains the specified element `filter()` : Creates a new array with every element in an array that pass a test... my confusion is, if filter already creates a new array with every element that passes this test: `return letters === ["a", "e", "i", "o", "u"]` then why do we have to use `include` after that test is done and the elements are already passed? Sorry man like I said I'm new to all this –  Apr 14 '22 at 15:15
  • 1
    Your test is wrong, that's the first thing I said. I replaced that test with one that uses `includes()`. – Barmar Apr 14 '22 at 15:16
  • 1
    `letters === ["a", "e", "i", "o", "u"]` will never be true. `letters` is a string, `["a", "e", "i", "o", "u"]` is an array, they can never be equal to each other. – Barmar Apr 14 '22 at 15:18
  • @Barmar I recognize my test was wrong but I just wanted to understand why `includes()` has to be added in when, to me, `filter()` seems to do the whole job by definition –  Apr 14 '22 at 15:20
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/243907/discussion-between-jordantocode11-and-barmar). –  Apr 14 '22 at 15:22
  • 1
    There's two things being done: `includes()` tests if an individual letter is a vowel. `filter()` returns all the letters for which this test is true. – Barmar Apr 14 '22 at 15:22

1 Answers1

0
const stringConvert = string => {
  let splitString = string.split("");
  let vowels = ["a", "e", "i", "o", "u"];
  let letters = {};
  splitString.forEach(l => {
    letters[l] = letters[l] ? letters[l] + 1 : 1;
  })
  let vowelsCount = [];
  vowels.forEach(l => vowelsCount[l] = letters[l]);
  return vowelsCount;
};
stringConvert("Why don't you try and split this string into vowels, please?");
alin0509
  • 451
  • 4
  • 5
  • There's nothing in the question about getting the count of each vowel separately. They just want an array of all the vowels, and then they can use `.length` to get the total count. – Barmar Apr 14 '22 at 15:10