以前、一度つくった事があるんですが、Node.js用に書き換えました。
また、「ランダムに数字を抽選しつつ、一巡するまでは同じ数字を抽選しない」は「非復元抽出」ということも親切な方に教えていただきました。
Lottery.js
"use strict"; class Lottery { constructor(length) { this._length = length; this._pod = []; this.reset(); } reset(opt_length = this._length) { this._pod = []; for (let i = 0; i < opt_length; ++i) { this._pod.push(i); } } select() { let num = this._pod.splice(Math.random() * this._pod.length | 0, 1)[0]; if (!this._pod.length) { this.reset(this._length); // 空になったらリセット } return num; } } module.exports = Lottery;
つかいかた
"use strict"; const Lottery = require("./Lottery"); let lottery = new Lottery(12); // 0 ~ 11までの中で抽選 for (let i = 0; i < 24; ++i) { // 試しに24回抽選してみる console.log(lottery.select()); }
こんな感じです。
非復元抽出は、非復元だけに、空になった後も復元しないものらしいのですが、
個人的には空になったらリセットする形を求められることが多いので、そちらを前提に作っています。
本当は空になった時はEventEmitterとかで通知して、ユーザーに処理を任せるほうが良いのかもしれません。