Feature #5584
closedArray#sample!
Description
=begin
ランダムに選択した要素をレシーバから取り除いて返すメソッドArray#sample!の追加を提案します。
配列からランダムに要素を取り出したい場合には
a = (1..5).to_a
a.delete_at(rand(a.size)) #=> 3
p a #=> [1, 2, 4, 5]
などと書く必要がありましたが、Array#sample!があれば
a = (1..5).to_a
a.sample! #=> 4
p a #=> [1, 2, 3, 5]
と簡潔に書く事ができます。
引数を指定した場合は、その数だけレシーバから要素を取り除き、新たな配列に取り除いた要素を入れて返します。
a = (1..10).to_a
p a.sample!(5) #=> [5, 4, 2, 6, 7]
p a #=> [1, 3, 8, 9, 10]
レシーバから選択した要素を取り去ってしまう事以外は、Array#sampleと同じ動作をします。
[].sample! #=> nil
[].sample!(1) #=> []
[1,2,3].sample!(random: rand) #=> 2
patchを添付します。
=end
Files
Updated by sorah (Sorah Fukumori) almost 13 years ago
もっと良いネーミングはない物でしょうかねえ.
ネーミングが微妙なような気がしてならない.
Updated by mame (Yusuke Endoh) almost 13 years ago
遠藤です。
2011年11月7日15:43 Masaki Matsushita glass.saga@gmail.com:
ランダムに選択した要素をレシーバから取り除いて返すメソッドArray#sample!の追加を提案します。
この機能はかつてから要望がありますが、まつもとさんが強硬に
反対しています。[ruby-core:18104] [ruby-core:18165]
sample! という名前が最大のネックのようですので、他の名前を
考えるといいと思います。
(案外まつもとさんの気が変わってる可能性もありますが)
--
Yusuke Endoh mame@tsg.ne.jp
Updated by Anonymous almost 13 years ago
近藤です
配列からランダムに要素を取り出したい場合には
a = (1..5).to_a
a.delete_at(rand(a.size)) #=> 3
p a #=> [1, 2, 4, 5]などと書く必要がありましたが、
a = (1..5).to_a.shuffle.each
a.next #=> 3
引数を指定した場合は、その数だけレシーバから要素を取り除き、新たな配列に取り除いた要素を入れて返します。
a = (1..10).to_a
p a.sample!(5) #=> [5, 4, 2, 6, 7]
p a #=> [1, 3, 8, 9, 10]
a = (1..10).to_a.shuffle.each
a.take(3) #=> [5, 4, 2, 6, 7]
Enumeratorを使ったほうが直感的だと思います。
Mitsuhiro Kondo
miche@mac.com
Updated by Glass_saga (Masaki Matsushita) almost 13 years ago
Mon, 7 Nov 2011 22:53:21 Yusuke Endoh :
sample! という名前が最大のネックのようですので、他の名前をえるといいと思います。
思いつくものとしてはpickやdrawといったところでしょうか。
個人的にはpickがしっくりきます。
Tue, 8 Nov 2011 00:44:07 近藤 充弘 :
Enumeratorを使ったほうが直感的だと思います
Enumerator#nextでは列挙状態が進みますが、Enumerable#takeでは進まないという問題があります。
a = (1..10).to_a.shuffle.each
a.take(3) #=> [10, 2, 6]
a.take(3) #=> [10, 2, 6]
Updated by mrkn (Kenta Murata) almost 13 years ago
むらたです。
(2011.11.08 15:39 ), Masaki Matsushita wrote:
Mon, 7 Nov 2011 22:53:21 Yusuke Endoh :
sample! という名前が最大のネックのようですので、他の名前をえるといいと思います。
思いつくものとしてはpickやdrawといったところでしょうか。
個人的にはpickがしっくりきます。
pick や draw から無作為操作である事を感じられないのは私だけでしょうか?
--
Kenta Murata muraken@gmail.com
1D69 ADDE 081C 9CC2 2E54 98C1 CEFE 8AFB 6081 B062
Updated by hasari (Hiro Asari) almost 13 years ago
「無作為抽出」は random sampling という用語がありますので、多少長くても Enumerable#random_sampling(n) ぐらいが適切かと思います。
#sample! が駄目で、#random_sampling が長過ぎるとなれば、この概念を導入するのに相応しい名前は無いように思われます。
Updated by sorah (Sorah Fukumori) almost 13 years ago
じゃあsample!になりますかねぇ...
pick からは少なくとも無作為抽出な動作を感じ取ることはできないですね.
Updated by Glass_saga (Masaki Matsushita) almost 13 years ago
確かにpickだけだと無作為に取り出す感じがありませんね。
pick_at_rand あるいは delete_at_rand はどうでしょう?
Updated by matz (Yukihiro Matsumoto) almost 13 years ago
まつもと ゆきひろです
In message "Re: [ruby-dev:44825] Re: [ruby-trunk - Feature #5584][Open] Array#sample!"
on Mon, 7 Nov 2011 22:53:21 +0900, Yusuke Endoh mame@tsg.ne.jp writes:
|2011年11月7日15:43 Masaki Matsushita glass.saga@gmail.com:
|> ランダムに選択した要素をレシーバから取り除いて返すメソッドArray#sample!の追加を提案します。
|
|この機能はかつてから要望がありますが、まつもとさんが強硬に
|反対しています。[ruby-core:18104] [ruby-core:18165]
|
|sample! という名前が最大のネックのようですので、他の名前を
|考えるといいと思います。
|(案外まつもとさんの気が変わってる可能性もありますが)
まだ賛成ではありません。
最大の理由がこのメソッドが副作用を積極的に利用・期待している
点で、最近流行のプログラミングスタイルに逆行していることで、
さらにsample!は他のArrayのメソッドと!による意味が変化してい
るという点でこの名前による導入には絶対に賛成しません。
要するに他のArrayクラスの!メソッドの基本的な動作は、「!の無
いものは元のArrayをコピーして操作したものを返す。元の配列は変
化なし。操作によって変化しない場合にはnilを返す※」、というも
のなのに対し、提案されているsample!は「sampleと同じ操作をする
と同時に元の配列を変更する」というものです。ここが気に入ら
ない。
もちろん、副作用を全否定するわけではないので、このメソッドが
あるとどれだけ便利であるかを力説された上で、適切と思われる名
前を提案していただければ、絶対に無理とまでは言いませんが、ハー
ドルは高いと思います。
※ 正確には Array#slice! はこの原則に従ってませんが、だからと
いって原則に従ってメソッドを増やすつもりはありません
まつもと ゆきひろ /:|)
Updated by sorah (Sorah Fukumori) almost 13 years ago
- File by_sorah.diff by_sorah.diff added
パッチをちょっと改善しました. (see by_sorah.diff)
- Array#sample, Array#sample! で処理が共通な部分が多いため,内部にさらに関数呼び出しを加え,フラグによって
動作の分岐をするようにした
本当はテストケースも書こうと思ったのですが,明日やります…
Updated by mame (Yusuke Endoh) over 12 years ago
- Status changed from Open to Rejected
まつもとさんの意見に対して feedback がないので閉じます。
--
Yusuke Endoh mame@tsg.ne.jp