Javascript で Ruby の Array.sample
ruby だと
array = ['a', 'b', 'c', 'd', 'e', 'f'] array.sample 4 #=> ["f", "c", "a", "b"]
みたいに書けるけれど Javascript のArray にそんな関数は無いので書いた。
Array.prototype.sample = function(num){ num = num === undefined ? 1 : num; var self = this; var random_iter = (function(){ // self の長さ分の 0 からの連番の配列をつくる var i = 0; var ary = Array.apply(null, Array(self.length)).map(function(){return i++}); return { has_next: function(){ return ary.length > 0; }, next: function(){ if(!this.has_next()) { return null; } // 配列からランダムにインデックスを取得する return self[ary.splice(Math.floor(Math.random() * ary.length),1)]; } } })(); return Array.apply(null, Array(num)).map(function(){ return random_iter.next(); }); };
ランダムな値を返すイテレータを作る方針で書いた。num の長さの空の配列作るだけでArray.apply(null, Array(num)
みたいに書かなくてはいけなくてとても悲しい思いをした。
常識的に考えて new Array(num)
でどうにかなってほしいと思う。言語仕様的に説明つかなくなるのはわかるけれど、気持ちの問題だと思う。
あと、世の中的に builtin の prototype を勝手に拡張するとモヒカンがやってきて殴られるみたいなのあるけれど、習作だから問題無いということにしていただきたい。