4

Ruby1.9に新しい列挙子があるのを見ましたslice_beforeAPIドキュメントはかなり不可解です。

特に、私はinitial_state価値をとるバリエーションに困惑しています。

たとえば、要素の累進和がある値を超えるたびに、数値を含む配列をサブ配列に分割したいとします。

a = [1,2,0,1,2,3]
a.slice_before(0) do |elem, sum|
  sum += elem
  sum > 3
end.to_a

期待される出力:

[[1,2,0], [1,2], [3]]

合計は「キャリー」や「メモ」のようなものだと思いますinjectが、それはうまくいかないようです。

このコードの不具合は不可解なエラーです。

TypeError: can't dup Fixnum
from (irb):43:in `each'

初期値としてslice_beforeを受け入れていないようです。Fixnumなんで?Rubyのバグ?

自分の状態変数を保持することでこれを回避できますが、私が探していた美しいRubyセマンティクスではありません。

sum = 0
a.slice_before do |elem|
  sum += elem
  sum > 3 && sum = 0
end.to_a

# => [[1, 2, 0], [1, 2], [3]]

それでinitial_state、この目的に使用できるかどうか?ドキュメントの例は、主にテキスト処理に関するもののようです。Ruby1.9.3p194を使用しています。

4

1 に答える 1

5

これinitial_stateは通常、キーと値のペアを格納する状態ハッシュです。

状態ハッシュを使用してコードを記述するには:

a.slice_before(sum: 0) do |elem, state|
  state[:sum] += elem
  if state[:sum] > 3
    # Reset the sum, so we'll get more elements
    state[:sum] = 0  
  end
end.to_a

メソッドはループごとに複製されるためinitial_state、メソッドに応答する必要があります。#dup

動作しない理由Fixnumは、 に応答しないため#dupです。各ループの状態を追跡できないため、Fixnum は機能しません。

于 2013-01-31T12:04:11.757 に答える