[解決済み] 繰り返しのない配列を効率的に選択する方法は?
2022-02-07 22:57:15
質問
この質問は様々な形で出回っていることは承知していますが、私の具体的な効率化の問題に関連する答えを見つけることができません。
私は以下のコードを持っていますが、うまく動作しています。
10項目の配列があり、そこからランダムに1項目を選択します(エンターキー押下時)。このコードでは、ランダムに選択できない直近の5つの選択肢を配列として保持しています(時間が経つと繰り返しが多くなるのを避けるため)。
chooseName()関数が最初に最近5回使用された名前を選択した場合、単に中断して再度自分自身を呼び出し、quot;ユニーク"な名前を見つけるまで繰り返すだけです。
2つ質問があります。
-
これは "再帰関数" と言っていいのでしょうか?
-
理論的には、一意な名前を見つけるまでに長い時間ループし続ける可能性があることが心配です - これを行うより効率的な方法はありますか?
よろしくお願いします。
var a = ["Roger", "Russell", "Clyde", "Egbert", "Clare", "Bobbie", "Simon", "Elizabeth", "Ted", "Caroline"];
var b = [];
var chooseName = function () {
var unique = true;
b.length = 5;
num = Math.floor(Math.random() * a.length);
name = a[num];
for (i = 0; i < a.length; i++) {
if (b[i] == name) {
chooseName();
unique = false;
break;
}
}
if (unique == true) {
alert(name);
b.unshift(name);
}
}
window.addEventListener("keypress", function (e) {
var keycode = e.keyCode;
if (keycode == 13) {
chooseName();
}
}, false);
解決方法は?
アイテムが選択されるたびに、そのアイテムを配列の後ろに移動させ、元の配列のスライスからランダムに選択します。
array.slice(0, -5)
.
var a = ["Roger", "Russell", "Clyde", "Egbert", "Clare", "Bobbie", "Simon", "Elizabeth", "Ted", "Caroline"];
var chooseName = function () {
var unique = true;
num = Math.floor(Math.random() * a.length - 5);
name = a.splice(num,1);
a.push(name);
}
window.addEventListener("keypress", function (e) {
var keycode = e.keyCode;
if (keycode == 13) {
chooseName();
}
}, false);
EDIT: これはまた、リストの末尾にある変数が最初のN回の呼び出しで考慮されないという不公平な不利益を与えないという副次的効果もあります。もしこれが問題なら、使用するスライスのサイズを記録するスタティック変数をどこかに保持して、B(この場合は5)で最大にするようにするといいかもしれません。 例
var a = ["Roger", "Russell", "Clyde", "Egbert", "Clare", "Bobbie", "Simon", "Elizabeth", "Ted", "Caroline"];
B = 5; //max size of 'cache'
N = 0;
var chooseName = function () {
var unique = true;
num = Math.floor(Math.random() * a.length - N);
N = Math.min(N + 1, B);
name = a.splice(num,1);
a.push(name);
}
関連
-
[解決済み】ある要素が可視DOMに存在するかどうかを確認するにはどうすればいいですか?
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] JavaScript で配列に値が含まれているかどうかを確認するにはどうすればよいですか?
-
[解決済み] 配列に特定のインデックスで項目を挿入する方法 (JavaScript)
-
[解決済み] オブジェクトが配列であるかどうかを確認するにはどうすればよいですか?[重複]。
-
[解決済み] ページを再読み込みせずにURLを変更するにはどうすればよいですか?
-
[解決済み] JavaScriptで配列を空にするにはどうしたらいいですか?
-
[解決済み] JavaScriptでオブジェクトのキー/プロパティの数を効率的にカウントする方法
-
[解決済み] 配列の最後の項目を取得する
-
[解決済み】配列に何かを追加する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】node.js TypeError: path must be absolute or specify root to res.sendFile [JSONのパースに失敗しました]。
-
[解決済み】Uncaught TypeError: nullのプロパティ'value'を読み取ることができない
-
[解決済み】SecurityError: オリジンを持つフレームがクロスオリジンフレームにアクセスするのをブロックした
-
[解決済み】jquery $.ajaxオブジェクトのresponseJSONプロパティを取得する方法 [重複]。
-
[解決済み】SyntaxError: 'import' と 'export' は 'sourceType: module' とだけ表示されるかもしれない - Gulp
-
[解決済み】JS ファイルが net::ERR_ABORTED 404 (Not Found) を取得する)
-
[解決済み] ローカルファイルを開くことができません - Chrome: ローカルリソースのロードが許可されていません
-
[解決済み】TypeError: res.status は関数ではありません。
-
[解決済み】このオブジェクトの "forEach "はなぜ関数でないのですか?
-
[解決済み】Syntax error: JavaScriptの不正なreturnステートメント