Feature #5584

Array#sample!

Added by Masaki Matsushita over 3 years ago. Updated over 3 years ago.

[ruby-dev:44817]
Status:Rejected
Priority:Normal
Assignee:-

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

patch.diff Magnifier (3 KB) Masaki Matsushita, 11/07/2011 03:43 PM

by_sorah.diff Magnifier (5.3 KB) Shota Fukumori, 11/08/2011 11:37 PM

History

#1 Updated by Shota Fukumori over 3 years ago

もっと良いネーミングはない物でしょうかねえ.

ネーミングが微妙なような気がしてならない.

#2 Updated by Yusuke Endoh over 3 years ago

遠藤です。

2011年11月7日15:43 Masaki Matsushita glass.saga@gmail.com:

ランダムに選択した要素をレシーバから取り除いて返すメソッドArray#sample!の追加を提案します。

この機能はかつてから要望がありますが、まつもとさんが強硬に
反対しています。

sample! という名前が最大のネックのようですので、他の名前を
考えるといいと思います。
(案外まつもとさんの気が変わってる可能性もありますが)

--
Yusuke Endoh mame@tsg.ne.jp

#3 Updated by Anonymous over 3 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

#4 Updated by Masaki Matsushita over 3 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]

#5 Updated by Kenta Murata over 3 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

#6 Updated by Hiro Asari over 3 years ago

「無作為抽出」は random sampling という用語がありますので、多少長くても Enumerable#random_sampling(n) ぐらいが適切かと思います。
#sample! が駄目で、#random_sampling が長過ぎるとなれば、この概念を導入するのに相応しい名前は無いように思われます。

#7 Updated by Shota Fukumori over 3 years ago

じゃあsample!になりますかねぇ...

pick からは少なくとも無作為抽出な動作を感じ取ることはできないですね.

#8 Updated by Masaki Matsushita over 3 years ago

確かにpickだけだと無作為に取り出す感じがありませんね。
pick_at_rand あるいは delete_at_rand はどうでしょう?

#9 Updated by Yukihiro Matsumoto over 3 years ago

まつもと ゆきひろです

In message "Re: 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!の追加を提案します。
|
|この機能はかつてから要望がありますが、まつもとさんが強硬に
|反対しています。
|
|sample! という名前が最大のネックのようですので、他の名前を
|考えるといいと思います。
|(案外まつもとさんの気が変わってる可能性もありますが)

まだ賛成ではありません。

最大の理由がこのメソッドが副作用を積極的に利用・期待している
点で、最近流行のプログラミングスタイルに逆行していることで、
さらにsample!は他のArrayのメソッドと!による意味が変化してい
るという点でこの名前による導入には絶対に賛成しません。

要するに他のArrayクラスの!メソッドの基本的な動作は、「!の無
いものは元のArrayをコピーして操作したものを返す。元の配列は変
化なし。操作によって変化しない場合にはnilを返す※」、というも
のなのに対し、提案されているsample!は「sampleと同じ操作をする
同時に元の配列を変更する」というものです。ここが気に入ら
ない。

もちろん、副作用を全否定するわけではないので、このメソッドが
あるとどれだけ便利であるかを力説された上で、適切と思われる名
前を提案していただければ、絶対に無理とまでは言いませんが、ハー
ドルは高いと思います。

※ 正確には Array#slice! はこの原則に従ってませんが、だからと
いって原則に従ってメソッドを増やすつもりはありません

                             まつもと ゆきひろ /:|)

#10 Updated by Shota Fukumori over 3 years ago

パッチをちょっと改善しました. (see by_sorah.diff)

  • Array#sample, Array#sample! で処理が共通な部分が多いため,内部にさらに関数呼び出しを加え,フラグによって 動作の分岐をするようにした

本当はテストケースも書こうと思ったのですが,明日やります…

#11 Updated by Yusuke Endoh over 3 years ago

  • Status changed from Open to Rejected

まつもとさんの意見に対して feedback がないので閉じます。

Yusuke Endoh mame@tsg.ne.jp

Also available in: Atom PDF