ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

# PatrickMcSweeny's solution

## to Word Count in the JavaScript Track

Published at Aug 23 2019 · 0 comments
Instructions
Test suite
Solution

#### Note:

This exercise has changed since this solution was written.

Given a phrase, count the occurrences of each word in that phrase.

For example for the input `"olly olly in come free"`

``````olly: 2
in: 1
come: 1
free: 1
``````

## Setup

Go through the setup instructions for Javascript to install the necessary dependencies:

https://exercism.io/tracks/javascript/installation

## Requirements

Install assignment dependencies:

``````\$ npm install
``````

## Making the test suite pass

Execute the tests with:

``````\$ npm test
``````

In the test suites all tests but the first have been skipped.

Once you get a test passing, you can enable the next one by changing `xtest` to `test`.

## Source

This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour.

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### word-count.spec.js

``````import { Words } from './word-count';

describe('words()', () => {
const words = new Words();

test('counts one word', () => {
const expectedCounts = { word: 1 };
expect(words.count('word')).toEqual(expectedCounts);
});

xtest('counts one of each', () => {
const expectedCounts = { one: 1, of: 1, each: 1 };
expect(words.count('one of each')).toEqual(expectedCounts);
});

xtest('counts multiple occurrences', () => {
const expectedCounts = {
one: 1, fish: 4, two: 1, red: 1, blue: 1,
};
expect(words.count('one fish two fish red fish blue fish')).toEqual(expectedCounts);
});

xtest('includes punctuation', () => {
const expectedCounts = {
car: 1, ':': 2, carpet: 1, as: 1, java: 1, 'javascript!!&@\$%^&': 1,
};
expect(words.count('car : carpet as java : javascript!!&@\$%^&')).toEqual(expectedCounts);
});

xtest('includes numbers', () => {
const expectedCounts = { testing: 2, 1: 1, 2: 1 };
expect(words.count('testing 1 2 testing')).toEqual(expectedCounts);
});

xtest('normalizes to lower case', () => {
const expectedCounts = { go: 3 };
expect(words.count('go Go GO')).toEqual(expectedCounts);
});

xtest('counts properly international characters', () => {
const expectedCounts = {
'Â¡hola!': 1, 'Â¿quÃ©': 1, 'tal?': 1, 'Ð¿Ñ€Ð¸Ð²ÐµÑ‚!': 1,
};
});

xtest('counts multiline', () => {
const expectedCounts = { hello: 1, world: 1 };
expect(words.count('hello\nworld')).toEqual(expectedCounts);
});

xtest('counts tabs', () => {
const expectedCounts = { hello: 1, world: 1 };
expect(words.count('hello\tworld')).toEqual(expectedCounts);
});

xtest('counts multiple spaces as one', () => {
const expectedCounts = { hello: 1, world: 1 };
expect(words.count('hello  world')).toEqual(expectedCounts);
});

xtest('does not count leading or trailing whitespace', () => {
const expectedCounts = { introductory: 1, course: 1 };
expect(words.count('\t\tIntroductory Course      ')).toEqual(expectedCounts);
});

xtest('handles properties that exist on Objectâ€™s prototype', () => {
const expectedCounts = {
reserved: 1, words: 1, like: 1, constructor: 1, and: 1, tostring: 1, 'ok?': 1,
};
expect(words.count('reserved words like constructor and toString ok?')).toEqual(expectedCounts);
});
});``````
``````export class Words {
count(inputString) {
let counts = {};
let words = inputString
.toLowerCase()
.trim()
.split(/\s+/);

words.forEach(function(word) {
counts[word] = words.filter(wordMatch => word === wordMatch).length;
});

return counts;
}
}``````