[#44295] p "135790123456789".delete("357") #=> "190124689" — take_tk <ggb03124@...>
以下は独り言なのですが、よろしかったら、String#delete の仕様が現在のよう
4 messages
2007/12/02
[#44310] プログラムに対して意図したとおりの文字列を渡す方法 — "Information Kanasansoft" <kanasansoft@...>
kanasanです。
9 messages
2007/12/05
[#44313] Re: プログラムに対して意図したとおりの文字列を渡す方法
— Kazuhiro NISHIYAMA <zn@...>
2007/12/05
西山和広です。
[#44322] mork.rb — "S_Konno(今野 滋)" <sk@...>
今野です。
6 messages
2007/12/06
[#44332] クラス:相互参照系の作成方法について質問です — "Saburoh Sakai" <sabroh@...>
はじめまして、さかいと申します。
12 messages
2007/12/11
[#44352] 配列のシャッフル — Maehara Masahide (前原正英) <maehrm@...>
前原と申します。
13 messages
2007/12/18
[#44353] Re: 配列のシャッフル
— "Takehiro Nagai" <lukesilvia@...>
2007/12/18
永井と申します。
[#44366] Rake改善プロジェクト — "Hajime Hoshi" <hajimehoshi@...>
東京大学修士 1 年の星一と申します。
14 messages
2007/12/19
[#44367] Re: Rake 改善プロジェクト
— NISHIMATSU Takeshi <t_nissie@...>
2007/12/19
西松と申します。
[#44386] 「Rubyリファレンスマニュアル刷新計画」1.9.0リリース — "原 悠" <yhara@...>
「Ruby リファレンスマニュアル刷新計画」メンバーのyharaです。
4 messages
2007/12/25
[#44398] DateTimeクラスでの時間加算について — "西塔伸一郎" <sinsaihy@...>
お世話になっております。
5 messages
2007/12/27
[#44402] ruby-refm-1.9.0-dynamic : Ruby 1.9 でうごかない — <mugenkai_151e@...>
ruby-refm-1.9.0-dynamic
4 messages
2007/12/27
[ruby-list:44361] Re: 配列のシャッフル
From:
"Takehiro Nagai" <lukesilvia@...>
Date:
2007-12-18 09:11:43 UTC
List:
ruby-list #44361
永井です。
>> 最初,aの要素は,5個あるので,collect は5回実行されると思うので,
ここが問題です。実際、問題のrandomize!では、
[1,2,3,4,5].randomize!
としてもブロック内の処理は5回は実行されません。
※collectが5回というよりは、collect内の処理(yield)が配列の各要素に対して1回ずつ、
計5回実行されます。
以下のようにすると、5回実行されていないのが分かります。
--------------------------------
class Array
def randomize!
result = collect { p "a"; slice!(rand(length)) }
replace result
end
def randomize
arr = self.dup
arr.randomize!
arr
end
end
a = [1,2,3,4,5]
p a.randomize!
--------------------------------
C:\>ruby problem.rb
"a"
"a"
"a"
[3, 4, 5]
--------------------------------
成瀬さんが貼って下さったソースを見ると、5回実行されない理由が分かります。
--------------------------------
static VALUE
rb_ary_collect(ary)
VALUE ary;
{
long i;
VALUE collect;
if (!rb_block_given_p()) {
return rb_ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr);
}
collect = rb_ary_new2(RARRAY(ary)->len);
for (i = 0; i < RARRAY(ary)->len; i++) {
rb_ary_push(collect, rb_yield(RARRAY(ary)->ptr[i]));
}
return collect;
}
--------------------------------
注目すべきは for (i = 0; i < RARRAY(ary)->len; i++) { です。
RARRAY(ary)->lenはRubyで言えば、array.lengthメソッドですね。
例えば、a = [1,2,3,4,5]として、問題のrandomize!を実行したとしましょう。
すると、最初の状態で、for (i = 0; i < RARRAY(ary)->len; i++) { の部分は下記のようになります。
for (i = 0; 0 < 5; i++) {
ここで、forループが1回終わると、iとRARRAY(ary)->lenの値は次のようになります。
i #=> 1
RARRAY(ary)->len #=> 4
ここでRARRAY(ary)->len が5から4に減った理由は、slice!で要素が取り除かれたためです。
そして、これが問題です。
2回目のループ後には
i #=> 2
RARRAY(ary)->len #=> 3
3回目のループ後には
i #=> 3
RARRAY(ary)->len #=> 2
ここでfor (i = 0; i < RARRAY(ary)->len; i++) に値をいれてみると
for (i = 0; 3 < 2; i++) となり、ループの継続条件が「偽」になるので、4回目の処理には行かず、ループは終了します。
よって、5回実行されるはずだった処理が3回で終わってしまい、結果の配列の長さは3となってしまいます。
いかがでしょうか?
07/12/18 に NARUSE, Yui <naruse@airemix.com> さんは書きました:
>
> 成瀬です。
>
> Maehara Masahide (前原正英) wrote:
> >> 最初,aの要素は,5個あるので,collect は5回実行されると思うので,
> >> a.slice!(rand(a.length)) を5回繰り返してみました。
> >
> > 以下の私の実行例だと,(*)の部分以下がダウトですね。
> >
> >> ====================================================================
> >> irb(main):027:0> a = [1,2,3,4,5]
> >> => [1, 2, 3, 4, 5]
> >> irb(main):028:0> a.slice!(rand(a.length))
> >> => 4
> >> irb(main):029:0> a
> >> => [1, 2, 3, 5]
> >> irb(main):030:0> a.slice!(rand(a.length))
> >> => 5
> >> irb(main):031:0> a
> >> => [1, 2, 3]
> >> irb(main):032:0> a.slice!(rand(a.length))
> >> => 1
> >> irb(main):033:0> a
> >> => [2, 3]
> >
> > (*)
> > ここの時点で,aの長さが2になっており,collect できない!
> > 私が最初,勘違いをしたのは,collect は,しだいに減っていく a に対して
> > 新たに実行されていくものと思っていました。
> > このような理解をしたのですが,よろしいでしょうか?
>
> たぶんソースを見た方が早いので、
> 以下に array.c の該当部分のソースを挙げておきました。
>
> static VALUE
> rb_ary_collect(ary)
> VALUE ary;
> {
> long i;
> VALUE collect;
>
> if (!rb_block_given_p()) {
> return rb_ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr);
> }
>
> collect = rb_ary_new2(RARRAY(ary)->len);
> for (i = 0; i < RARRAY(ary)->len; i++) {
> rb_ary_push(collect, rb_yield(RARRAY(ary)->ptr[i]));
> }
> return collect;
> }
>
>
> --
> NARUSE, Yui <naruse@airemix.com>
> DBDB A476 FDBD 9450 02CD 0EFC BCE3 C388 472E C1EA
>
>