Enhancing a Voting System Using JavaScript

Introduction

Welcome back to a fascinating session where we will learn about enhancing existing functionality without causing regressions. Our scenario today involves designing a voting system. We'll start with the basic implementation of the voting system and gradually introduce additional elements of complexity.

Starter Task Review

In our initial task, we create a simple voting system in JavaScript with a set of basic functionalities:

  • registerCandidate(candidateId: string): boolean: This method is used for adding new candidates to our system.
  • vote(timestamp: number, voterId: string, candidateId: string): boolean: This method is designed to facilitate users in casting their votes. Each vote is given a timestamp.
  • getVotes(candidateId: string): number | null: This method retrieves the total number of votes for a given candidate.
  • topNCandidates(n: number): Array<string>: We also want to add a leaderboard functionality to our system. This method returns the top n candidates sorted by the number of votes.

Initial Solution Development

Let's jump into the JavaScript code and begin the implementation of our starter task. Here, we use JavaScript objects and Maps as the core of our design. These structures will allow us to dynamically manage lists keyed based on candidate IDs and voter IDs, greatly simplifying our design.

class VotingSystem {
  constructor() {
    this.candidates = new Map(); // Stores candidateId as key and votes as value
    this.voters = new Map(); // Tracks each voter's voting history
  }

  registerCandidate(candidateId) {
    if (this.candidates.has(candidateId)) {
      return false; // Candidate is already registered
    }
    this.candidates.set(candidateId, 0); // Initialize candidates with 0 votes
    return true;
  }

  vote(timestamp, voterId, candidateId) {
    if (!this.candidates.has(candidateId)) {
      return false; // Returns false if candidate is not registered
    }

    if (!this.voters.has(voterId)) {
      this.voters.set(voterId, { votes: [], timestamps: [] });
    }

    const voterData = this.voters.get(voterId);
    voterData.votes.push(candidateId); // Record the vote
    voterData.timestamps.push(timestamp); // Record the time of the vote
    this.candidates.set(candidateId, this.candidates.get(candidateId) + 1); // Increment vote count for the candidate
    return true;
  }

  getVotes(candidateId) {
    return this.candidates.get(candidateId) || null; // Retrieve vote count for a candidate, or null if not found
  }

  topNCandidates(n) {
    return Array.from(this.candidates.keys())
      .sort((a, b) => this.candidates.get(b) - this.candidates.get(a))
      .slice(0, n); // Return top `n` candidates based on votes
  }
}
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal