配列から重複せずにランダムで取り出す(違いが分かる奴が足跡を残すスレ)

昔は"*"なんてつけてなかったような。

function rnd (n) {
  return Math.floor (Math.random () * n);
}


function* fisher_yates (ary) {
  for (let n; n = ary.length; )
    yield ary.splice (rnd (n), 1)[0];
}

こんなのを書いてみたが、効率の良いアルゴリズムがダメダメになっているような気がする

配列から重複せずにランダムで取り出す

重複しないといっても全部取り出した後、再度シャッフルすると連続して取り出されるケースがある。そこで第二引数に最低限次に出てくるまでの回数を設けられるようにしてみた

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]];
      } 
    }
  }
}

教えてgoo の回答で、俺の余計な波型インデントを取り除くブックマークレット(改良版)

複数の回答をソートして1つにまとめて、波型インデントを取り除くやつ

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('').replace(/^( *)/gm,''))},!1))()