アプリ版:「スタンプのみでお礼する」機能のリリースについて

javascriptでの重複しないくじの作り方を教えてください。

A 回答 (5件)

No1です



簡単なサンプルを作成してみました。
仕組みとしてはNo1の1)の方式です。

ボタンを押すと、くじNo01~20までの項目からくじを引いてゆき、重複しないようにします。
20回を超えるごとに再度くじNo01~20を作成し直しますので、例えば、15回目~25回目のくじの中では重複がある可能性はあります。

※ くじ引きの結果は、順に下方に追加表示されるようにしてあります。
※ 最初に50回だけ、スクリプトが勝手にくじ引きを行います。

<!DOCTYPE HTML>
<html lang="ja">
<head><title>Sample</title>
</head>
<body>
<p>くじを引く:
<input type="button" id="draw" value="push to draw" />
</p>

<h4>結果</h4>
<div id="result" style="width:60em;"></div>

<script type="text/javascript">
//*** くじの定義 ***//
var Lottery = {
items : [],
refresh : function(){
for(var i=1; i<=20; i++) this.items.push("くじNo" + ("0" + i).substr(-2));
},
draw : function(){
if(!this.items.length) this.refresh();
var n = Math.floor(Math.random()*this.items.length);
return this.items.splice(n, 1);
}
};

//*** ボタンクリック時の処理 ***//
document.getElementById("draw").addEventListener("click", function(){
var r = Lottery.draw();
var e = document.getElementById("result");
e.innerHTML += (e.innerHTML?", ":"") + r;
}, false);

//*** 50回自動でくじ引きを行う ***//
var count = 0;
var id = setInterval(function(){
if(count++<50) document.getElementById("draw").click(); else clearInterval(id);
} , 600);

</script>
</body>
</html>
    • good
    • 1
この回答へのお礼

分かりやすい回答ありがとうございます。

お礼日時:2018/03/10 13:37

#4です


ブックマークレットが失敗でした。訂正します。これを登録してこのページで起動して解答欄でクリックすると取り出せるはず。

javascript:((l=/^\s*\/\/(?:@(\D.*))?(?::(\d+))/,I='a_text',c,o,O='textContent')=>document.addEventListener('click',({target:_})=>{_.className==I&&(c=l.exec(_[O]))&&alert(Array.from(_.ownerDocument.querySelectorAll('div.'+I)).map(_=>_[O]).filter(_=>(o=l.exec(_))&&o[1]==c[1]).sort((e,_)=>l.exec(e)>l.exec(_)).join(''))},!1))()
    • good
    • 0

//@babu_babu_baboo:1


//なにがどうわからないのか、わかりません。まぁいつものことですけど。(全角空白は半角に置換のこと)
//関数 *Shaffle は、いつもと違う。*が付いている。
//そう!違いの分かる奴になれよ!

<!DOCTYPE html>
<html lang="ja">
 <meta charset="UTF-8">
 <style>
 body > p {
   font-size: 180px;
    color: green;
   }
    </style>
     <body>
      <p>おみくじ!</p>
      
       <script>
        
        function* Shaffle (a = [ ], w = 0) {
         w = Math.min (a.length, Math.max (w, 0));
         let rnd = n => Math.floor (Math.random () * n);
        
         for (let i = 0, I = a.length, c = I - w; true; ) {
         if (i)
        yield a[--i];
       else {
       for (let j = i = I; j; j--) {
      let
     k = j - 1,
    n = (c < j)
    ? w + rnd (j - w)
   : rnd (j);
  [a[n], a[k]] = [a[k], a[n]];
  }
  }
}
}

 const
  unsei = '大吉,中吉,小吉,吉,半吉,末吉,末小吉,凶,小凶,半凶,末凶,大凶'.split (',');
 
  let omikuji = {
    p: document.querySelector ('p'),
    kuji: Shaffle (unsei, unsei.length / 2 |0),
     handleEvent: function (e) {
      this.p.textContent =
       e.target == this.p
       ? this.kuji.next ().value
        : 'おみくじ!';
         }
        };
        
        document.addEventListener ('click', omikuji, false);
        </script>

//ここまで
/* 波型のインデントを取り除くブックマークレット(実験中なので成功するかはわからないけど)
javascript:((l=/^\s*\/\/(?:@(\D.*))?(?::(\d+))/,I='a_text',c,o,O='textContent')=>document.addEventListener('click',({target:_})=>{_.className==I&&(c=l.exec(_[O]))&&alert(Array.from(_.ownerDocument.querySelectorAll('div.'+I)).map(_=>_[O]).filter(_=>(o=l.exec(_))&&o[1]==c[1]).sort((e,_)=>l.exec(e)>l.exec(_)).join(''))},!1)
*/
    • good
    • 0

こうですかね?


<script>
var a=Object.keys(Array(10).fill(null));
a.sort(function(x,y){
return Math.random()<0.5?1:-1;
});
console.log(a);
</script>

※ランダムな配列が入手できる
    • good
    • 0

こんにちは



「くじ」とのことなので、例えば、結果の項目が列挙されている配列(大吉、中吉・・・など)からランダムで選択するような仕組みになっているものとします。

>重複しないくじ
とのことなので、一度その項目が選択された時に
 1)元の配列からその項目を削除する
または
 2)その項目に「出現済み」フラグなどを立てる
  (別配列などでも可能)

としておいて、くじ引きの際に、1)の場合はそのまま引けば重複はありませんし、2)の場合はフラグが立っていたら再度引き直す(フラグの立っていないものが出るまで繰り返す)といった方法で実現可能です。

いずれの場合も、選択の対象数が減っていきますので、対象がなくなってもくじを引こうとするとおかしなことになりますから、初期値に戻して2巡目とするなどの処理が必要になるかも知れません。

さらに、2)の考え方の場合は、数が大きな選択肢で残りが少ない場合には、無駄にトライする回数が増えるので、「多くの選択肢の中から、少ない回数のくじを引く」といった場合に限る方が良いかもしれません。
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!