class Tracker { _servers = []; /** * * @param {string} hostType * @example * allocate("south") */ allocate(hostType) { const nextAvailableServer = this._nextAvailableServer(this._servers); this._servers.push(nextAvailableServer); return `${hostType}${nextAvailableServer}`; } /** * * @param {string} hostName * @example * deallocate("south3") */ deallocate(hostName) { console.log(`Removing ${hostName} from servers...`); const numberMatch = hostName.match(/\d+/)[0]; const serverNumber = Number(numberMatch); const updatedServers = this._servers.filter((s) => s !== serverNumber); console.log(`Servers after removal of ${hostName}: ${updatedServers}`); this._servers = updatedServers; } /** * * @param {Array} servers * @example * _nextAvailableServer([5,3,1]) * @returns number */ _nextAvailableServer(servers) { if (!servers.length) { return 1; } // Operate on sorted servers to assure loop always runs the same const sortedServers = servers.sort(); let lowestAvailable; let counter = 1; sortedServers.forEach((server) => { if (server !== counter) { lowestAvailable = counter; return; } // This keeps track of the incremental server numbers counter++; }); return lowestAvailable || counter; // If there are no available in range of server array, just return counter (next) } } const tracker = new Tracker(); const test1 = tracker._nextAvailableServer([5, 3, 1]); const test2 = tracker._nextAvailableServer([3, 2, 1]); console.log("servers at start:", tracker._servers); tracker.allocate("south"); tracker.allocate("south"); tracker.allocate("south"); console.log(tracker.allocate("south")); console.log(tracker.allocate("south")); console.log(tracker.allocate("south")); console.log(tracker.allocate("south")); console.log(tracker.deallocate("south5")); console.log(tracker._servers);