Rubyリファレンス: Home

chunk (Enumerable)

Edit   History

Ruby 1.9.2

標準クラス・モジュール > Enumerable > chunk

enum.chunk {|item| block }

chunkメソッドは、ブロックの戻り値ごとに要素の並びをまとめた配列を作ります。戻り値はEnumeratorオブジェクトです。Enumeratorオブジェクトのeachメソッドを呼び出すと、eachのブロック引数には「chunkのブロックの戻り値、戻り値に対応する配列」が入ります。

次の例は、文字列中の各文字をcharsメソッドで取り出し、chunkメソッドでEnumeratorを作ります。chunkのブロックでは、英数字(:word)かそれ以外(:other)で文字を分類します。Enumeratoreachを呼び出すと、chunkの戻り値ごとにまとめられた配列を取り出せます。

enum = "Ruby is  cool!".chars.chunk {|ch| ch =~ /\w/ ? :word : :other }
enum.each {|key, arr| puts "#{key}: #{arr.inspect}" }
word: ["R", "u", "b", "y"]
other: [" "]
word: ["i", "s"]
other: [" ", " "]
word: ["c", "o", "o", "l"]
other: ["!"]

上記の例は、メソッドチェーンを使って次のように書けます。

"Ruby is  cool!".chars.chunk {|ch|
  ch =~ /\w/ ? :word : :other
}.each {|key, arr|
  puts "#{key}: #{arr.inspect}"
}

chunkのブロックでnilまたは:_separatorを返すと、Enumeratoreachにはその要素は含まれなくなります。

"Ruby is  cool!".chars.chunk {|ch|
  ch =~ /\w/ ? :word : nil
}.each {|key, arr|
  puts "#{key}: #{arr.inspect}"
}
word: ["R", "u", "b", "y"]
word: ["i", "s"]
word: ["c", "o", "o", "l"]

chunkのブロックで:_aloneを返すと、要素をまとめた配列ではなく、1要素からなる配列ができます。次の例では、英数字でも空白でもない文字を1つずつ取り出します。

"Ruby is  cool!?".chars.chunk {|ch|
  case ch
  when /\w/  then :word
  when /\s/  then nil
  else :_alone
  end
}.each {|key, arr|
  puts "#{key}: #{arr.inspect}"
}
word: ["R", "u", "b", "y"]
word: ["i", "s"]
word: ["c", "o", "o", "l"]
_alone: ["!"]
_alone: ["?"]
enum.chunk(state) {|item, state| block }

chunkメソッドの引数にオブジェクトを渡すと、ブロック中でそのオブジェクトをメモ代わりに利用できます。オブジェクトはブロックの第2引数に入ります。オブジェクトはdupでコピーされるので、数値などdupできないオブジェクトは渡せません。

次の例では、引数にハッシュを渡して「前の文字」を記録し、連続した空白を1要素からなる配列にしています。

"Ruby  is   cool!?".chars.chunk({}) {|ch, memo|
  last, memo[:last] = memo[:last], ch
  case ch
  when /\w/  then :word
  when /\s/  then last =~ /\s/ ? nil : :space
  else :_alone
  end
}.each {|key, arr|
  puts "#{key}: #{arr.inspect}"
}
word: ["R", "u", "b", "y"]
space: [" "]
word: ["i", "s"]
space: [" "]
word: ["c", "o", "o", "l"]
_alone: ["!"]
_alone: ["?"]

関連項目