引数のあるイテレータ

スポンサーリンク
スポンサーリンク
ライフスタイル関連のコンテンツ
お金 | 仕事 | 勉強 | プライベート | 健康 |
プログラミング関連のコンテンツ
C言語/C++入門 | Ruby入門 | Python入門 | プログラミング全般

以下のエントリーの続きです。

スポンサーリンク

クラス内にイテレータ定義
イテレータ定義で複数の引数をブロックに渡す

ここまでは・・・

def each_all
    @proflist.each{|prof|
        yield(prof.name, prof.age, prof.country)    
        }
end

のように、イテレータのメソッド自体(each_allメソッド)には引数を渡していませんでした。
しかし、each_allメソッドに引数を渡して、イテレータ定義することもできます。
これまでの例と同様のProfListクラスとテストルーチンで、出身国が日本かアメリカ(/Japan|America/)の人のみを抽出するイテレータを定義して試してみます。

イテレータの使い方は、以下のようになります。

pattern = /Japan|America/
proflist.each_find(pattern){|prof|
    puts "#{prof.name} - age:#{prof.age} country:#{prof.country}"
}

つまり、正規表現patternにマッチする出身国の人のみ抽出してイテレートを試みる。
イテレータ定義のほうは、以下の通り。

def each_find(country_match)
    @proflist.each{|prof|
        if country_match =~ prof.country
            yield(prof)
        end
    }
end

引数country_matchに、正規表現パターンが渡されます。
そして、if文によりマッチしたプロフィールだけ抽出して、yield文を実行します。
では、以下クラス定義の完成形とテストルーチン。

require "pp"
 
# 1人のプロフィールのクラス。名前、年齢、出身国
class Prof
    attr_accessor :name, :age, :country
    def initialize(name, age, country=nil)
        @name = name
        @age = age
        @country = country
    end
end
 
# プロフィールのリストのクラス
class ProfList
    def initialize()
        @proflist = Array.new
    end
    # 新しい人を加える
    def add(prof)
        @proflist.push(prof)
    end
    # 人数を返す
    def length
        @proflist.length
    end
    # n番目の人を別の人に入れ替える
    def []=(n, prof)
        @proflist[n] = prof
    end
    # n番目の人を返す
    def [](n)
        @proflist[n]
    end
    # リストからプロフィールを削除
    def delete(prof)
        @proflist.delete(prof)
    end
    # イテレータ定義
    def each
        @proflist.each{|prof|
            yield(prof)    
        }
    end
    # イテレータ定義2。名前のみイテレート。
    def each_name
        @proflist.each{|prof|
            yield(prof.name)    
        }
    end
    # イテレータ定義3。名前、年齢、出身国のイテレート。
    def each_all
        @proflist.each{|prof|
            yield(prof.name, prof.age, prof.country)    
        }
    end
    # イテレータ定義4。/Japan|America/の人のみ抽出
    def each_find(country_match)
        @proflist.each{|prof|
            if country_match =~ prof.country
                yield(prof)
            end
        }
    end
end
 
# テストルーチン
proflist = ProfList.new
 
# プロフィールをいくつか作る
p1 = Prof.new("Tom William", 45, "America")
p2 = Prof.new("De Pedoro", 23, "Spain")
p3 = Prof.new("Naoko Yamada", 37, "Japan")
 
# プロフィールリストに人(プロフィール)を追加
proflist.add(p1)
proflist.add(p2)
proflist.add(p3)
 
# プロフィールを1人ずつ表示。
# ProfListクラスの独自定義イテレータ。
puts "--- original iterator"
proflist.each{|prof|
    puts "#{prof.name} - age:#{prof.age} country:#{prof.country}"
}
 
# 名前のみイテレート。
puts "--- name only iterator"
proflist.each_name{|name|
    puts name
}
 
# 名前、年齢、出身国のイテレート。
puts "--- name,age,country iterator"
proflist.each_all{|name, age, country|
    puts "#{name} - age:#{age} country:#{country}"
}
 
# 出身国が日本かアメリカ(/Japan|America/)の人のみ抽出してイテレート
puts "--- /Japan|America/ iterator"
pattern = /Japan|America/
proflist.each_find(pattern){|prof|
    puts "#{prof.name} - age:#{prof.age} country:#{prof.country}"
}
 

実行結果。

--- original iterator
Tom William - age:45 country:America
De Pedoro - age:23 country:Spain
Naoko Yamada - age:37 country:Japan
--- name only iterator
Tom William
De Pedoro
Naoko Yamada
--- name,age,country iterator
Tom William - age:45 country:America
De Pedoro - age:23 country:Spain
Naoko Yamada - age:37 country:Japan
--- /Japan|America/ iterator
Tom William - age:45 country:America
Naoko Yamada - age:37 country:Japan
スポンサーリンク
 
スポンサーリンク