Compute count of unique words using ES6 sets I have written a function which counts how many unique words are included in a given text.

The source-code:



const computeCountUniqueWords = (strToExamine) =&gt; {
  let parts = strToExamine.split(" ");

  let validWords = parts.filter((word) =&gt; {
    return /^\w/.test(word);
  });

  let uniqueWords = new Set(validWords);

  return uniqueWords.size;
}

let text1 = "Lorem ipsum dolor sit amet consectetuer adipiscing elit aenean commodo ligula eget dolor.";
let text2 = "Etiam ultricies nisi vel augue. Curabitur ullamcorper";

console.log(`Text 1 has ${computeCountUniqueWords(text1)} words`);
console.log(`Text 2 has ${computeCountUniqueWords(text2)} words.`);




I think it has become quite neat and short. 

Nevertheless: Is there a better way to solve the described task? 

Moveover: Is my checking with the regular expression sufficient? Or should it be enhanced?

Looking forward to reading your answers.
Two problems

Your code has two problems. 


It does not remove punctuation from the words resulting in the same words not matching. Eg text1 has 12 unique words not 13. You count dolor and dolor. as different words.
You are ignoring capitalization. You would count Dolor and dolor as different words rather than the same. 


String.match

Update I was not paying attention on first posting. There is no /*RegExp.match*/

The better solution is to use the String.match to convert the matches to an array and then directly create the set from that. The code is just one line and the performance is 2.5 times faster than using String.replace as shown.

thus the ideal solution becomes...

const uniqueWords = txt =&gt; new Set(txt.toLowerCase().match(/\w+/g)).size;


String.replace

You can use a string replace to iterate over RegExp matches. It's a little hacky but I much prefer it over other methods such a using a RegExp to split the string, or RegExp.match, or RegExp.exec which have an ugly interface and are slower than String.replace.

Converting the text to lowercase  using String.toLowerCase solves the capitalization problem



const countUniqueWords = text =&gt; {
    const words = new Set();
    text.toLowerCase().replace(/\w+/g, word =&gt; words.add(word));
    return words.size;        
}




const a = "Lorem ipsum dolor sit amet consectetuer adipiscing elit aenean commodo ligula eget dolor.";
const b = "Etiam ultricies nisi vel augue. Curabitur ullamcorper.";
info1.textContent = `A has ${countUniqueWords(a)} unique words`;
info2.textContent = `B has ${countUniqueWords(b)} unique words.`;
 
&lt;code&gt;A: "Lorem ipsum dolor sit amet consectetuer adipiscing elit aenean commodo ligula eget dolor."&lt;/code&gt;&lt;/br&gt;
&lt;code id="info1"&gt;&lt;/code&gt;&lt;br&gt;
&lt;code&gt;B: "Etiam ultricies nisi vel augue. Curabitur ullamcorper."&lt;/code&gt;&lt;/br&gt;
&lt;code id="info2"&gt;&lt;/code&gt;