So the only thing stopping your function from working as expected is numWords.length
, which should be changed to simply numWords
, as it's already the length of the array that you wish to iterate over. When you change that, your code works as expected.
It seems though, that you also wanted some tips on style and design of the function, so I went ahead and tweaked a few things.
function allTheCounts(str) {
var wordArray = str.split(" ");//get array of words
var wordLengths = 0;//initalize wordLengths to 0
for (var i = 0; i < wordArray.length; i++) {
wordLengths += wordArray[i].length;
}
return {
numWords: wordArray.length,
numCharacters: str.length,
numSpaces: wordArray.length - 1,
avgWordLength: wordLengths/wordArray.length//Use Math.round(10*wordLengths/wordArray.length)/10 to round to one decimal place
};
}
allTheCounts("Hello world. It is a good day.");
Removing unnecessary intermediate variables
You'll notice that your function has gotten a little long, and has more local variables than it has results. We can correct this by trying to find where we've duplicated our efforts. Clearly we shouldn't need to do a split(' ')
more than once on the same string, so we just store the split array in one var, and reference that array's length when we want to use the number of words in our string. This same logic is applied a few times to remove several unnecessary lines of code. This makes the function much easier to read, and even has the potential to increase efficiency.
Important note!
Tabs or other whitespace characters won't show up as spaces between words. Two words that are separated by only a newline will be counted as a single word, etc. It's also important to consider that allTheCounts("Hello world. It is a good day.");
will result in 22 words being detected, because, when splitting up things by spaces, several zero-length strings will be added to wordArray. If you'd like to remove these zero-length entries in the array, you can see this SO answer.
For a way more efficient way of doing the average (removing the for loop from the function entirely), see Max's solution below. Folding his clever math into this function gives this almost-one-liner:
function allTheCounts(str) {
var wordArray = str.split(" ");//get array of words
return {
numWords: wordArray.length,
numCharacters: str.length,
numSpaces: wordArray.length - 1,
avgWordLength: (str.length - (wordArray.length - 1))/wordArray.length
};
}
allTheCounts("Hello world. It is a good day.");