0

I'm trying to write a function that when given a string, returns an object where each key is a word in the given string, with its value being how many times that word appeared in the given string.

Here's what I have:

function countWords(str) {
  var strArray = str.split(' ');
  var output = {};

  if(str.length === 0) {
    return output;
  } else {
    strArray.map(function(n) {
      output[n] = str.split(n).length - 1;
    });
  }
  return output;
}

Here's the console output when I add...

console.log(strArray);
console.log(output);

...to the code:

Object { a: 4, ask: 1, bunch: 3, get: 1, try: 1 } ["ask", "a", "bunch", "try", "a", "bunch", "get", "a", "bunch"]

For some reason, the number of occurrences of 'a' is 1 too high but all the others are correct.

Anyone see what I'm doing wrong?

  • 1
    What is the function being called with? What input? – CertainPerformance Oct 19 '18 at 07:04
  • 1
    Possible duplicate of [Counting words in javascript and push it into an object](https://stackoverflow.com/questions/40102199/counting-words-in-javascript-and-push-it-into-an-object) – VLAZ Oct 19 '18 at 07:06
  • Although I'm not sure it's actually a duplicate after re-reading this question. This one is "I have an algorithm and it doesn't work correctly" instead of "I don't have an algorithm". The title misled me. – VLAZ Oct 19 '18 at 07:08

3 Answers3

1

The problem is that when you do

str.split(n)

if n is short, especially if it's a single character, like a, then likely occurrences of it inside of other words in the string will be split as well. For example, 'abc a abc'.split('a') will result in an array of length 4 even though there's only one a in the string.

One possible step towards a solution would be to use a regular expression, and put word boundaries around the word:

output[n] = str.split(new RegExp(String.raw`\b${n}\b`)).length - 1

But it would be more elegant not to use intermediate arrays, and use reduce instead:

const countWords = str => str.split(' ').reduce((a, word) => {
  a[word] = (a[word] || 0) + 1;
  return a;
}, {});

console.log(countWords('ask a bunch, try a bunch, get a bunch'));
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • I ended up using Jonas Wilms's answer because it was the simplest. However, I found yours very helpful as well cause it allowed me to research some technologies I haven't used before. Thank you very much! – Matthew Garry Oct 19 '18 at 18:10
  • `.map` is not appropriate at all when you're not going to use the mapped result - `.reduce` *is* the right method to use when you need to reduce an array into a single object. – CertainPerformance Oct 19 '18 at 19:03
  • Got it! Thanks for keeping me on track. – Matthew Garry Oct 20 '18 at 00:21
0

Instead of the inner split just increase the count by one:

 strArray.forEach(function(n) {
  output[n] = (output[n] || 0) + 1;
 });
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
-1

To count no of occurrences of word, given string can be split by space or you can use to read word by word using space as a delimiter.

Here is the sample example in java, in this example java Scanner class is used to read word by word from a given input stream, if the word matches, counter values will be incremented.

import java.util.Scanner;

public class WordOccurrencesInGivenString {
    public static void main(String[] args) {
        String word = "try";
        try (Scanner s = new Scanner(System.in)) {
            int counter = 0;
            String str = null;
            do {
                str = s.next();
                if (str.equals(word)) {
                    ++counter;
                }
            } while (!str.equals("exit"));
            System.out.println("No of occurrences of a word [" + word + "] : " + counter);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

in this example "exit" word is used to stop the reading of data from input stream and to print the no of occurrences of a word.

  • Java is to Javascript as Pain is to Painting, or Ham is to Hampster. They are completely different. OP is trying to debug his *Javascript* program. – CertainPerformance Oct 19 '18 at 19:04