Set

Prompt
Implement a custom Set
class in JavaScript that manages a collection of unique values. Your class should support the following methods:
set(key, value)
: Adds a new key-value pair to the set. If the key already exists, update its value.get(key)
: Returns the value associated with the key. If the key does not exist, return undefined.has(key)
: Checks if the key exists in the set and returns a boolean.unset(key)
: Removes the key and its associated value from the set.
Constraints:
- All keys will be strings.
- The values can be of any type.
Note: Ensure your implementation does not allow duplicate keys and efficiently handles lookups, updates, and deletions.`
A set is a collection of unique values, where each value can occur only once.
Consider what underlying data structure you might use to implement the set. An object can be a straightforward option, allowing you to use the keys to store the unique values of the set.
The has method can be implemented by checking if the given value exists as a key in the object using the hasOwnProperty method.
The unset method can be implemented by using the delete operator to remove the key-value pair corresponding to the given value from the object, but only if the key exists.
Solution
Explanation
There are several key concepts to understand when implementing a custom Set class in JavaScript: The Set implementation uses an object as its underlying data structure to store key-value pairs. This approach provides:
- O(1) time complexity for lookups and modifications
- Natural key uniqueness handling
- Efficient memory usage
- Easy implementation of all required operations
Constructor Initialization
constructor(data = {}) {
this.state = typeof data === 'object' && data !== null ? data : {};
}
The constructor creates our storage object, accepting an optional initial data object. It performs a safety check to ensure we're working with a valid object or creating an empty one if needed.
Setting Values
set(key, val) {
this.state[key] = val;
}
The set
operation directly assigns the value to the key in our state object. Since JavaScript objects naturally handle key uniqueness, if the same key is used again, it automatically updates the existing value rather than creating a duplicate. This way, every key stays unique.
Getting Values
get(key) {
return this.state[key];
}
Retrieval is straightforward - we directly access the value using the key. If the key doesn't exist, JavaScript naturally returns undefined
, matching our requirements.
Checking Existence
has(key) {
return this.state.hasOwnProperty(key);
}
The has
method uses hasOwnProperty
to check if the key exists in our state object. This is more reliable than direct property access as it only returns true for properties directly on the object, not those inherited from the prototype chain.
Removing Values
unset(key) {
if (this.has(key)) {
delete this.state[key];
}
}
Deletion first checks if the key exists (to avoid unnecessary operations) and then uses the delete
operator to remove the key-value pair entirely from the object.
Performance Considerations 🚀
When implementing a Set, it's crucial to understand the performance implications of your chosen data structure. Using a plain JavaScript object as the underlying storage mechanism provides several benefits:
- Constant-time Operations: Most operations (get, set, has, unset) have O(1) time complexity
- Memory Efficiency: Only stores what's needed with minimal overhead
- Built-in Key Management: JavaScript objects handle key uniqueness automatically
Common Pitfalls
In JavaScript, arrays come equipped with a set of built-in
methods and properties that allow you to manipulate and
interact with them. A common mistake—especially under the
pressure of interviews—is confusing methods and
properties, particularly when it comes to accessing an
array's length
, and using methods like push()
, pop()
, and
shift()
.
Understanding the Difference
Properties: Properties of an array are accessed without parentheses. They provide information about the array or give access to static information. The most commonly accessed property is length
, which gives you the number of elements in an array.
const arr = [1, 2, 3, 4];
console.log(arr.length); // Output: 4
Methods: Methods are functions associated with the array object, which you call using parentheses. These methods perform operations on the array, such as adding or removing elements. Examples include push()
, pop()
, and shift()
.
const arr = [1, 2, 3, 4];
// Adds an element to the end
arr.push(5); // arr is now [1, 2, 3, 4, 5]
// Removes the last element
arr.pop(); // returns 5, arr is now [1, 2, 3, 4]
// Removes the first element
arr.shift(); // returns 1, arr is now [2, 3, 4]
Common Mistakes
- Attempting to call
length
as a method (i.e.,arr.length()
), which will result in a TypeError sincelength
is a property, not a function. - Forgetting to call array methods with parentheses (e.g., writing
arr.shift
instead ofarr.shift()
), which results in the method not being executed.