Array#eachで要素追加
- 質問:Array#eachのブロック中で条件によって要素が追加される場合、追加された要素もeachで取り出せるか?
- プログラムの結果を確認すると、pushされた要素もeachで取り出せることが示されている。
- したがって、ブロックの中で要素を追加してもeachは追加された要素を漏れなく処理する。
- ベストアンサー
Array#eachのブロック中で要素追加
初歩的な質問で申し訳ありません ary = [Foo.new] ary.each do |i| if (条件) ary.push(Foo.new) end end 上の様にブロックの中である条件でaryに要素が追加されます。 この場合、この追加された要素はeachで漏れなく扱えるのでしょうか? 簡単なプログラムで試した限りではpushされたFooインスタンスについてもeachで取り出せているようなのですが、自信が無いので質問致します。 # coding: windows-31J class Foo attr_accessor :checked attr_reader :val RAND_MAX = 5 def initialize rnd = Random.new @checked = false @val = rnd.rand(RAND_MAX).to_i end end ary = [Foo.new] ary.each do |f| if f.val > 0 ary.push(Foo.new) end f.checked = true end cnt_true = 0 cnt_false = 0 ary.each_index do |idx| print "#{idx} #{ary[idx].checked} #{ary[idx].val}\n" if ary[idx].checked cnt_true += 1 else cnt_false += 1 end end puts "checked true = #{cnt_true}" puts "checked false = #{cnt_false}" よろしくお願いします。
- siffon9
- お礼率69% (585/836)
- Ruby
- 回答数1
- ありがとう数2
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
Array#eachではイテレート毎に要素数のチェックをしてるので、後ろに足していく pushなら問題ないみたいです。イテレート中のpopも大丈夫です。 でも、Arrayの先頭を操作する、shiftやunshiftでは内部ループカウンタとインデックスが ずれるのでダメですね。 一応CRubyの実装をコピペしときます。 array.c: VALUE rb_ary_each(VALUE ary) { long i; RETURN_ENUMERATOR(ary, 0, 0); for (i=0; i<RARRAY_LEN(ary); i++) { // ←イテレート毎に長さのチェック rb_yield(RARRAY_PTR(ary)[i]); } return ary; }
関連するQ&A
- VB.NET Form1からForm2を開いたり閉じたりする方法
VB.NET2005でForm1にあるCheckBoxをTrueにするとform2をモードレスフォームとして開き、CheckBoxをFalseにするとform2を閉じる方法がわかりません。また、form2の[×]で閉じた時にはForm1にあるCheckBoxをFalseにする方法がわかりません。 '----------------------------------- Private Sub CheckBox2_CheckedChanged ・・・ Dim f_cnt As Integer Dim form2 As New Form2() f_cnt = My.Application.OpenForms.Count If CheckBox1.Checked = True Then If f_cnt = 1 Then form1.Show() 'モードレスフォームとして表示する Else form2.Close() ←閉じない End If End Sub '-----------------------------------
- ベストアンサー
- Visual Basic
- Ruby 文法 ブロックの中で メソッドを呼ぶ
class Hoge def val 'aaa' end def piyo yield end end h=Hoge.new h.piyo do p h.val #<ーここの話 end 上の様に書く時、ブロックの中で、そのクラスのメソッドを呼ぶ時、上の例だと h.val と書いてますが、これself.valなどと書きたいのですがERRになってしまいます。 h.と書くのがとても嫌なのですが、なにか良い書き方あるのでしょうか?
- ベストアンサー
- Ruby
- 【ruby】無名関数?でブロック付きメソッドって作れませんか?
Proc.new do|arg| arg.each do |x| puts x end end.call([1,2,3,4,5]) 上記のようなものを無名関数と理解しているのですが、 これを下記の様にすると、 Proc.new {|arg| arg.each do |x| yield(x) end }.call([1,2,3,4,5]) do |x| puts x end no block given とエラーになってしまいます。 無名関数で、ブロック付きメソッドって作れないものでしょうか? ご指導の程、宜しくお願いいたします。
- ベストアンサー
- Ruby
- 計算の途中経過を表示
以下のようなプログラムで、素数をカウントダウンする事が出来るのですが、このくらいのサイズだとどうしても次の素数が表示されるまで時間がかかります。 そこで以下のものを修正して、今どの数に取りかかっていて、どの約数(i)で割っているのか常に画面に表示されるようにしたいのです。値が画面で目まぐるしく変わってもかまいません。是非助けてください。 def prime(val) maxv = Math::sqrt(val).truncate (2..maxv).each do |i| return false if val % i == 0 end return true end x = 10**17+1 until x<10**16 until prime(x) x=x-2 end puts x x=x-2 end puts x
- ベストアンサー
- Ruby
- VB6でゲームパッドの情報取得方法について
Visual Basic初心者です。 ビデオ入力が2回路あるキャプチャーボード用でVB6で作られたSDKソフトを修正して使っています、ゲームパッドのボタンを押す事で入力1、2の切換をしようとしていますがうまくいきません。 現状はフリーのゲームパッド情報取得モジュールを追加してDo・・・Loopで回していますが肝心のキャプチャーが動かなくなります、DoとLoopを外せば問題なくキャプチャーできます。 Do Call GetJoy 'ゲームパッド情報取得 'AV入力の切換 If JoyBtn And 1 Then 'AV1選択 Call DXMediaCapApi.DXSetVideoSource(CardNo(0), 1) MenuAV1.Checked = True MenuAV2.Checked = False MenuSvideo.Checked = False End If If JoyBtn And 2 Then 'AV2に切換 Call DXMediaCapApi.DXSetVideoSource(CardNo(0), 2) MenuAV1.Checked = False MenuAV2.Checked = True MenuSvideo.Checked = False End If DoEvents Loop End Sub こんな感じです。 ” Private Sub Jyoypadbut_Click() ” のような方法は無いのでしょうか?、ご教授宜しくお願い致します。
- ベストアンサー
- Visual Basic
- クラスや構造体のarrayを作りたい。
クラスや構造体のarrayを作りたい。 クラスや構造体のarrayを作りたいのですが、 以下の方法で正しいのでしょうか? ==================================== #include <string> #include <vector> class Test{ public: std::string sono1; int sono2; bool sono3; //コンストラクタ Test(std::string tmp_sono1,int tmp_sono2,bool tmp_sono3){ sono1=tmp_sono1; sono2=tmp_sono2; sono3=tmp_sono3; } }; void main(){ std::vector<Test> testObjArray; testObjArray.push_back(*(new Test("てすと1",1,true))); testObjArray.push_back(*(new Test("てすと2",2,false))); } ==================================== 質問1: コンストラクタ時、クラス内の変数へ引数の値を渡す時、 上記のようにtmpを作成する以外の方法はありますか? 質問2: push_back時、クラスをインスタンスしてvectorに渡すにはこのような記述であってるのでしょうか? 「testObjArray.push_back(*(new Test("てすと1",1,true)));」 一応問題なく動いているようなのですが心配です。 よろしくお願いします。
- ベストアンサー
- C・C++・C#
- if文からcase文への置き換え
ピクチャボックスをクリックしたら、チェック ボックスがチェックされるメソッドを作りたいと 思っています。 Private Sub PictureBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click,PictureBox2.Click 'ここから If sender Is PictureBox1 Then If Me.CheckBox1.Checked = False Then Me.CheckBox1.Checked = True Else Me.CheckBox1.Checked = False End If ElseIf sender Is PictureBox2 Then If Me.CheckBox2.Checked = False Then Me.CheckBox2.Checked = True Else Me.CheckBox2.Checked = False End If End If 'ここまで End Sub 上記のif文をCase文に置き換えたくて、 'ここから Select Case sender Case PictureBox1 If Me.CheckBox1.Checked = False Then Me.CheckBox1.Checked = True Else Me.CheckBox1.Checked = False End If Case PictureBox2 If Me.CheckBox2.Checked = False Then Me.CheckBox2.Checked = True Else Me.CheckBox2.Checked = False End If End Select 'ここまで 上記のように書き換えたのですが、エラーが出てしまいます(ビルドは通るのですが)。 Case文の使い方が間違っているんだとは思いますが、どこがどう 間違っているのがよくわかりません。 ご教授いただけないでしょうか?
- ベストアンサー
- Visual Basic
- これを実行するには
私の知り合いにプログラムを作ってもらったのですが、どうすればよいのかまったくわかりません。どうすればよいでしょうか。 ↓このようなものです。 #include <stdio.h> #include <stdlib.h> #include <time.h> typedef int BOOLEAN; BOOLEAN TRUE = 1; BOOLEAN FALSE = 0; int main(void) { int wc,c,rnd; BOOLEAN dec[50] = {FALSE}; c = wc = 0; dec[0] = TRUE; srand(time(NULL)); while(1){ rnd = rand() % 49; if(dec[rnd] == FALSE){ dec[rnd] = TRUE; if(wc == 6){ printf("%0*d\n",2, rnd); c++; wc = 0; if(c == 49){ break; } } else{ printf("%0*d,",2, rnd); c++; wc++; } if(c == 24){ printf("00,"); c++; wc++; } } } return 0; }
- ベストアンサー
- その他(プログラミング・開発)
- ユーザーフォーム上でFor Each~Next?
Excelユーザーフォームでマルチページを使用しているのですが テキストボックスに文字(パスワード的なもの)を入力したら マルチページ内の特定ページのコントロールをenabled=trueにしたいのです(通常はenebledがtrue・falseの混合ページです) 先日よりFor Each~Next構文を使い始めたのですが勉強不足『オブジェクト・コレクション』の概念がいまいち理解できません。よろしくお願いします。 ネット上で調べてコピペしたのですがこのままだと他のページ、ページ外のコントロールまで影響するので良い方法をアドバイスしていただけますか?やはりコントロール個別にコードを書くしかないのでしょうか? Private Sub TextPASS_Change() If TextPASS.Value = "aaaa" Then For Each Control In Controls 省略(enabled=true) Next Else For Each Control In Controls 省略(enabled=false) Next End If End Sub
- ベストアンサー
- その他MS Office製品
お礼
ご回答ありがとうございました。 rubyのソースまでご確認いただいて恐縮です。 とりあえずpushしか使用しないので、問題ないと伺って安心しました。もしダメだったら全ての要素がチェックされたかの確認のためのループを置かないといけないかな、と思っていたのですが必要ないですね。 ちなみに試しに上のテストプログラムのpushをunshiftに書き換えてみたところ、要素が追加された場合はプログラムが無反応になりました。仰るとおりうまく行かないようです。