Skip to content

Instantly share code, notes, and snippets.

@Peranikov
Created July 26, 2017 11:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Peranikov/6a84d89249272cad22f178024c872275 to your computer and use it in GitHub Desktop.
Save Peranikov/6a84d89249272cad22f178024c872275 to your computer and use it in GitHub Desktop.
5-5-4 Enumerator
# 様々なクラスがEnumeratorを返すメソッドを持っている
[].each
{}.each
(1..10).each
''.each_char
10.times
# loop
#to_enum/enum_forメソッドでも得られる
[1,2,3].to_enum
'Alice'.enum_for(:each_char)
# Enumeratorは生成元のメソッドを使ってEnumerableのメソッドを提供する
lines = <<EOM
Alice
Bob
Charlie
EOM
enum = lines.each_line # => <Enumerator ...>
enum.map {|line| line.length } # => [6, 4, 8]
# with_indexで添字と一緒にループさせる
%w(Alice Bob Charlie).each.with_index do |name, index|
puts "#{index}: #{name}"
end # "1: Alice" "2: Bob" "3: Charlie"
# selectなどのメソッドと組み合わせられる
%w(Alice Bob Charlie).select.with_index do |name, index|
index > 0
end # ["Bob", "Charlie"]
# 外部イテレーターでループを制御する
enum = [4,4,2,3]
enum.next # => 4
enum.next # => 4
enum.next # => 2
enum.rewind # 初めからやり直す
enum.next # => 4
enum.next # => 4
enum.next # => 2
enum.next # => 3
enum.next # StopIterationが発生
enum = [4,4,2,3]
loop do
puts enum.next
end # 4,4,2,3 と出力しStopIterationはloopで補足される
# 2つのArrayを同時に繰り返す例
people = %w(Alice Bob Charlie).to_enum
ages = [14, 32, 28].to_enum
loop do
person = people.next
age = ages.next
puts "#{person} (#{age})"
end # "Alice (14)" "Bob (32)" "Charlie (28)"
# Enumerator#feedでselectの引数を後から渡せる
enum = %w(Alice Bob Charlie).select
loop do
begin
person = enum.next
enum.feed /li/ === person # (ブロックの戻り値にあたる値)
rescue => e
# StopIteration#result
p e.result # ["Alice", "Charlie"] と表示(selectの戻り値)
break
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment