Project

General

Profile

Actions

Feature #5584

closed

Array#sample!

Added by Glass_saga (Masaki Matsushita) over 12 years ago. Updated about 12 years ago.

Status:
Rejected
Assignee:
-
Target version:
[ruby-dev:44817]

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

patch.diff (3 KB) patch.diff Glass_saga (Masaki Matsushita), 11/07/2011 03:43 PM
by_sorah.diff (5.3 KB) by_sorah.diff sorah (Sorah Fukumori), 11/08/2011 11:37 PM

Updated by sorah (Sorah Fukumori) over 12 years ago

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

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

Updated by mame (Yusuke Endoh) over 12 years ago

遠藤です。

2011年11月7日15:43 Masaki Matsushita :

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

この機能はかつてから要望がありますが、まつもとさんが強硬に
反対しています。[ruby-core:18104] [ruby-core:18165]

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

--
Yusuke Endoh

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

Updated by Glass_saga (Masaki Matsushita) over 12 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) over 12 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
1D69 ADDE 081C 9CC2 2E54 98C1 CEFE 8AFB 6081 B062

Actions #6

Updated by hasari (Hiro Asari) over 12 years ago

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

Actions #7

Updated by sorah (Sorah Fukumori) over 12 years ago

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

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

Actions #8

Updated by Glass_saga (Masaki Matsushita) over 12 years ago

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

Updated by matz (Yukihiro Matsumoto) over 12 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 writes:

|2011年11月7日15:43 Masaki Matsushita :
|> ランダムに選択した要素をレシーバから取り除いて返すメソッドArray#sample!の追加を提案します。
|
|この機能はかつてから要望がありますが、まつもとさんが強硬に
|反対しています。[ruby-core:18104] [ruby-core:18165]
|
|sample! という名前が最大のネックのようですので、他の名前を
|考えるといいと思います。
|(案外まつもとさんの気が変わってる可能性もありますが)

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

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

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

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

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

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

Updated by sorah (Sorah Fukumori) over 12 years ago

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

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

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

Updated by mame (Yusuke Endoh) about 12 years ago

  • Status changed from Open to Rejected

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

--
Yusuke Endoh

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0