Trouble with word counting function

Hi All,
I’m trying to put together a function that takes a paragraph and returns the length of the longest sentence in that paragraph.

Here’s what I have so far: https://www.codecademy.com/workspaces/61ebc489e82514494196213b

Despite my best efforts the function returns 34 when it should return 32. While investigating why that is I noticed some other weird behaviour that I don’t understand, so I’m just left scratching my head.
What’s going wrong here? Is there an easier way to do this that I’m missing?
Any tips would be very welcome, thank you!

function countWords(str){ const stringArray = (str.split('!').join('$').split('?').join('$').split('.').join('$').split('$')); let answer = 0; for (i = 0; i < stringArray.length; i++){ let senLength = stringArray[i].split(' ').length; senLength; if (answer < senLength){ answer = (senLength); };} return answer;} const exampleText = "It's been said that everybody loves Raymond. However, new studies suggest that Raymond is less well liked than we previously assumed - of out a hundred applicants, only eighteen individuals responded to a question about their love for Raymond positively! Almost half of applicants requested more information, asking \"Who the ■■■■ is this Raymond guy? What's so great about him? Why should I give him my heart so readily?\" More on this emerging story at eight." console.log(countWords(exampleText));

It seems to be counting the space at the beginning of the string and it seems to be counting the ‘-’ as words.

Here’s what I used to try to debug that:

function countWords(str){ const stringArray = (str.split('!').join('$').split('?').join('$').split('.').join('$').split('$')); //console.log(stringArray) let answer = 0; let answerSentenceArr; let j; // index of longest for (i = 0; i < stringArray.length; i++){ let senLength = stringArray[i].split(' ').length; if (answer < senLength){ answer = (senLength); j = i; };} //console.log(j); answerSentenceArr = stringArray[j].split(' '); for (let i = 0; i < answerSentenceArr.length; i++) { console.log(`(${i+1}) ${answerSentenceArr[i]}`); } return answer;} const exampleText = "It's been said that everybody loves Raymond. However, new studies suggest that Raymond is less well liked than we previously assumed - of out a hundred applicants, only eighteen individuals responded to a question about their love for Raymond positively! Almost half of applicants requested more information, asking \"Who the ■■■■ is this Raymond guy? What's so great about him? Why should I give him my heart so readily?\" More on this emerging story at eight." console.log(countWords(exampleText));

here:

let senLength = stringArray[i].split(' ').length;

You might want to remove some of the elements from that array before finding its length.
Using .filter [for arrays] after the .split(' ') you have is one possible way to do so.
(Hint: don’t use any strings in there that are just empty strings, only a space, or only '-' ; or only use strings that contain letters).

On visual inspection we can see two contractions and an improper use of the ndash. There is not supposed to be white space around an emdash. Since we are only counting words and sentence length, we could also remove the double quotes. We can manually replace these…

sampleText = exampleText.replace("It's been", "It has been").replace("What's", "What is").replace(" - ", ": ").replace(/"/g, '')

The colon is the grammatical equivalent of an emdash.

That gives us:

'It has been said that everybody loves Raymond. However, new studies suggest that Raymond is less well liked than we previously assumed: of out a hundred applicants, only eighteen individuals responded to a question about their love for Raymond positively! Almost half of applicants requested more information, asking Who the ■■■■ is this Raymond guy? What is so great about him? Why should I give him my heart so readily? More on this emerging story at eight.'

Now we want to split on full stop characters to break out the sentences.

sentenceArray = exampleText.split(/[.:!?]/g)

That will give us eight sentences of which one is empty. We can break out the words into their own arrays and trim any residual white space…

sentenceArrays = []
sentenceArray.forEach(function (sentence) {
  this.push(sentence.trim().split(' '))
}, sentenceArrays)

which gives us,

[
['It', 'has', 'been', 'said', 'that', 'everybody', 'loves', 'Raymond']
['However,', 'new', 'studies', 'suggest', 'that', 'Raymond', 'is', 'less', 'well', 'liked', 'than', 'we', 'previously', 'assumed']
['of', 'out', 'a', 'hundred', 'applicants,', 'only', 'eighteen', 'individuals', 'responded', 'to', 'a', 'question', 'about', 'their', 'love', 'for', 'Raymond', 'positively']
['Almost', 'half', 'of', 'applicants', 'requested', 'more', 'information,', 'asking', 'Who', 'the', '■■■■', 'is', 'this', 'Raymond', 'guy']
['What', 'is', 'so', 'great', 'about', 'him']
['Why', 'should', 'I', 'give', 'him', 'my', 'heart', 'so', 'readily']
['More', 'on', 'this', 'emerging', 'story', 'at', 'eight']
['']
]

We can discard the last element…

sentenceArrays.pop()

Now we can build a length index…

lenCounts = sentenceArrays.map((x, i) => [x.length, i])

which gives,

[
[8, 0]
[14, 1]
[18, 2]
[15, 3]
[6, 4]
[9, 5]
[7, 6]
]

To find the longest sentence we just need to sort, and the one at the end will give us both index and length.

lenCounts.sort(function(a, b) {return  a[0] - b[0]})

which gives us,

[
[6, 4]
[7, 6]
[8, 0]
[9, 5]
[14, 1]
[15, 3]
[18, 2]
]

The longest sentence is,

longest = lenCounts.slice(-1)
console.log(longest)
// [18, 2]
console.log(sentenceArray[2]])
1 Like

Thanks so much for your in depth reply! Will take some time to go through your advice. I’m pretty new to coding so you going through step by step for me is invaluable, really appreciated.

1 Like

Thank you for the tips! Will give that a try and see how I do.