The Problem
Write a function that will return the count of distinct case-insensitive alphabetic characters and numeric digits that occur more than once in the input string. The input string can be assumed to contain only alphabets (both uppercase and lowercase) and numeric digits.
Examples
duplicateCount('abcde')
=>0
– no characters repeats more than onceduplicateCount('aabbcde')
=>2
– ‘a’ and ‘b’duplicateCount(aabBcde)
=>2
– ‘a’ occurs twice and ‘b’ twice (b and B)
My Thought Process Before Sets
Prior to encountering Javascript Sets, I’d have gone about this problem by:
-
First converting the text passed into the function to a uniform letter casing, then …
-
Create an empty javascript object which I’d use to track each character of the passed argument. Next up, I’ll …
-
Loop over the string, making each character a property of the empty object created above. This is a two-step process being that …
-
If the character doesn’t exist on the object, it is added as a new property and its value set to 1.
-
If, however, the character already exists on the object, its value is incremented by 1.
-
After completely iterating through the string, I’ll then iterate over the object and push properties which have values > 1 to an array which I’d call ‘dupes’.
-
After iterating over the object, I’d return the length of the dupes array, since that would contain all duplicates present in the provided string.
Here’s a valid implementation of what this idea would look like:
function duplicateCount(text) {
const tracker = {};
const dupes = [];
for (const char of text.toLowerCase()) {
if (tracker.hasOwnProperty(char)) {
tracker[char]++;
} else {
tracker[char] = 1;
}
}
for (const prop in tracker) {
if (tracker[prop] > 1) dupes.push(prop);
}
return dupes.length;
}
My Thought Process After Sets
However, since learning that “the Set object lets one store unique values of any type”, this is how I went about the challenge.
-
Create two sets, one for all the characters in the provided string (tracker) and another for characters which appear more than once (dupes).
-
Iterate over a uniform-cased version of the provided string checking if the tracker has the current character.
-
If true, dump it in the dupes set, otherwise, add it to the tracker set.
-
After iteration, simply return the size of the dupes set since every character dumped there would only appear once. That is, if during iteration say for a string like “For loop” which has 3 ‘o’ characters, instead of adding two ‘o’s to the dupes set, only one ‘o’ would be added as sets can only contain unique values.
Here’s a working implementation of this idea:
function duplicateCount(text) {
if (!text) return 0; // no need moving forward if input is empty
const tracker = new Set(); // keep track of all characters in the input
const dupes = new Set(); // keep track of duplicate characters
for (const char of text.toLowerCase()) {
if (tracker.has(char)) {
dupes.add(char);
} else {
tracker.add(char);
}
}
return dupes.size;
}
Refs: