2
\$\begingroup\$

wordList is an array of non-empty strings ("words"). The following code I have written with the purpose of obtaining a Map, containing the unique words and their respective count:

for (let p = 0; p < wordList.length; p++) {
  const word = wordList[p];

  if (wordMap.has(word)) {
    wordMap.set(word, wordMap.get(word) + 1); //increase frequency of word
  } else {
    wordMap.set(word, 1); //add word
  }
}

I'd like to know if there is a better way to obtain this frequency distribution. Although the code seems to be working, feels a bit awkward (I am aware of the existence of the reducer(), but I have difficulty figuring it out).

If possible, I'd Like also to know how to make this case insensitive.

\$\endgroup\$
0
2
\$\begingroup\$

General review points

  • Rather than use a for(;;) loop use a for...of loop as you dont need the idx p for anything but indexing the word array.

    for (const word of wordList) {
    
  • You don't need the comments as what is happening is obvious in the code.

  • You can combine the get and set into one expression by using the ?? (Nullish coalescing operator) to check for undefined.

    wordMap.set(word, (wordMap.get(word) ?? 0) + 1);
    
  • Always create functions rather than flat code. Even when only showing example code.

Reducer

"... (I am aware of the existence of the reducer(), but I have difficulty figuring it out) ..."

Is not needed in this case but can be use if so desired. (See last rewrite)

Array.reduce a reference if needed.

Rewrite

There are several ways you can write the function

function mapWordCounts(words) {
    const counts = new Map();
    for (const word of words) { counts.set(word, (counts.get(word) ?? 0) + 1) }
    return counts;
}

Or using Array.forEach

function mapWordCounts(words) {
    const counts = new Map();
    words.forEach(word => counts.set(word, (counts.get(word) ?? 0) + 1));
    return counts;
}

Or with a reducer in an arrow function which will save the need for the return token as return are implied in arrow functions with out a delimited {} code body. This only works because Map.set return the map when called.

const mapWordCounts = words => words.reduce(
        (counts, word) => counts.set(word, (counts.get(word) ?? 0) + 1), new Map()
    );
\$\endgroup\$
1
  • \$\begingroup\$ Thank you, very kind. Your answer is very helpful \$\endgroup\$
    – Pam
    Oct 13 at 6:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.