-1

I'm new to programming and I wanted to make a word frequency counter where it finds the most frequent word and has it pop up as an alert. Although I have read some articles I can't seem to find a proper solution. For example, I want my alert to say the most frequent word in the text area is "Hello" 2. Any help will be appreciated.

enter image description here

function countWords() {
    let input = document.getElementById("input").value;
    var counter;
    for(var i = 0; i < input.length; i++) {
        if(input[i] == input[i+1]){
            counter = counter + 1;
        }
    }
    alert(counter);
}
<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="main.js"></script>
</head>

<body>
    <textarea id="input" rows="30" cols="30"></textarea><br>
    <button type="button" onclick="countWords()">Count Repeated Words</button>
</body>
</html>
isherwood
  • 58,414
  • 16
  • 114
  • 157
Caz
  • 11
  • 6
  • 3
    The value of a ` – Pointy May 02 '23 at 15:43
  • the value of input is the entire content of your textarea... – Chris G May 02 '23 at 15:45
  • 1
    @Yogi that seems like a significantly different issue. Also the answer is kind-of wrong. – Pointy May 02 '23 at 15:47
  • As @Pointy said I know that is a String value but I have tried .split and I just cant figure out how to split the string and count individual words. For example I don't want to count whitespace. – Caz May 02 '23 at 15:50
  • Are the words always separated by whitespace? @Caz – Unmitigated May 02 '23 at 15:51
  • @Unmitigated yes. – Caz May 02 '23 at 15:52
  • `let words = input.split(/\s+/)` – Barmar May 02 '23 at 15:52
  • You need to take the value of the input and then create an array of words. You could do this using the [split() method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) along with a [regex](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet) to only accept letters or what you would constitute as a "word". Once you have an array of the words, you could then iterate over the array and count like words. – dale landry May 02 '23 at 15:52
  • Why are you comparing each word to the next word? – Barmar May 02 '23 at 15:52
  • @Barmar now that you pointed that out I see the mistake there. – Caz May 02 '23 at 15:53
  • And the correct logic is not going to be similar to what you posted. You have to keep track of how many times you "see" each distinct word. The easiest way to do that is to have an object with each word as a property name. The value of each property would be the count. Then you can find the biggest count (or keep track of it as you go through the words). – Pointy May 02 '23 at 16:01

1 Answers1

0

Here's a solution, tried to comment each step:

function countWords() {
  let input = document.getElementById("input").value;
  let counters = {};

  input
    // to lower case
    .toLowerCase()
    // split on space
    .split(' ')
    // remove non word - characters (.! etc)
    .map(x => x.replace(/\W/g, ''))
    // count number of occurences of each word
    .forEach(x => counters[x] = (counters[x] || 0) + 1);

  // sort counters
  let byOccurence = Object.entries(counters)
    .sort((a, b) => b[1] - a[1]);

  alert(
    'The 5 words that occur the most times are:\n' 
    + byOccurence.slice(0, 5).map(([word, times]) =>
      `${word} ${times}\n`).join('')
  );

}

countWords();
Thomas Frank
  • 1,404
  • 4
  • 10
  • 1
    You don't need to sort to find the maximum. Finding the maximum should be a linear operation. – Unmitigated May 02 '23 at 16:15
  • True, that would optimize the performance. But: There can be many words with the same count so if you want to keep them all, sorted ;) ... sort does the trick. – Thomas Frank May 02 '23 at 16:18
  • Thank you that was the solution i was looking for but I need to study the lines first so I can understand what exactly every command does. Much appreciated. – Caz May 03 '23 at 17:18