Implement an event emitter
Company: Snowflake
Role: Frontend Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates understanding of event-driven programming and API design in a frontend environment, specifically the ability to manage event listener registration, removal, and invocation while preserving listener ordering and independent event storage.
Constraints
- 0 <= len(operations) <= 10000
- eventName, listenerId, and emitted arguments are strings of length 1 to 100
- Multiple listeners may be registered for the same event and must be invoked in registration order
- If the same listener is registered multiple times for the same event, each registration counts separately
- off(eventName, listenerId) removes only the first remaining matching registration for that event and does nothing if no such listener exists
- Emitting an event with no registered listeners produces no output
Examples
Input: ([['on','click','first'],['on','click','second'],['emit','click','10','20']],)
Expected Output: [['first','10','20'],['second','10','20']]
Explanation: Both click listeners are invoked in registration order with the emitted arguments.
Input: ([['on','click','A'],['on','hover','B'],['on','click','C'],['off','click','A'],['emit','click','x'],['emit','hover','y']],)
Expected Output: [['C','x'],['B','y']]
Explanation: Removing A from click leaves C for click. The hover listener B is stored independently.
Input: ([['emit','ready'],['off','ready','missing'],['on','ready','A'],['off','ready','B'],['emit','ready','ok']],)
Expected Output: [['A','ok']]
Explanation: Emitting with no listeners and removing missing listeners do nothing. A remains registered and is invoked.
Input: ([['on','message','A'],['on','message','A'],['on','message','B'],['off','message','A'],['emit','message','hello'],['off','message','A'],['emit','message','again']],)
Expected Output: [['A','hello'],['B','hello'],['B','again']]
Explanation: A was registered twice. The first off removes only one A, so A and B receive the first emit. The second off removes the remaining A.
Input: ([['on','open','L'],['on','close','L'],['off','open','L'],['emit','open'],['emit','close']],)
Expected Output: [['L']]
Explanation: The same listener ID can be registered for different events independently. The close event emits with no extra arguments.
Input: ([],)
Expected Output: []
Explanation: With no operations, there are no listener invocations.
Hints
- Use a dictionary/hash map from event names to an ordered list of listeners.
- For off, scan only the listener list for that event and remove the first matching listener ID.