1

私はオブジェクトを持っていますtreetreeというプロパティがありますtree.elementstree.elements要素と、場合によっては他のサブツリーの両方を含む配列で、独自のelements配列を持つことになります。

オブジェクトが特定のクラスの場合、ツリー内のオブジェクトを置き換えることができるメソッドが必要です。問題は要素をインラインで置き換えることです。

明らかに、以下は機能しません。

[1,2,3].each { |n| n = 1 }
# => [1,2,3]

ただし、これは次のようになります。

a = [1,2,3]
a.each_with_index { |n, idx| a[idx] = 1 }
# => [1,1,1]

ただし、次のように、再帰関数を使用してループし、プレースホルダーをコンテンツに置き換えています。

def replace_placeholders(elements)
    elements.each do |e|
        if e.respond_to?(:elements) and e.elements.any?
            replace_placeholders(e.elements)
        elsif e.is_a? Placeholder
            e = "some new content" # << replace it here
        end
    end
end

インデックスの追跡は非常に複雑です。試してみましe.replace("some new content")たが、うまくいきません。これについて最善の方法は何ですか?

4

2 に答える 2

3

その場で更新しようとするのではなく、新しい配列を作成します。これらの行に沿った何かが機能するはずです:

def replace_placeholders(elements)
  elements.map do |e|
    if e.respond_to?(:elements) and e.elements.any?
      e.elements = replace_placeholders(e.elements) # replace array
      e  # return e itself, so that map works correctly.
    elsif e.is_a? Placeholder
      "some new content"
    end
  end
end
于 2012-07-04T07:23:45.903 に答える
1

Array#collect を使用します。

[1,2,3].collect { |n| 1 }
# => [1,1,1]

そして、このブロック パラメーターを使用して、好きなことを行います。

したがって、コードは次のようになります。

elements.collect{ |n| if n.respond_to?(:elements) and n.elements.any?
        replace_placeholders(n.elements)
    elsif n.is_a? Placeholder
        "some new content" # << replace it here
    end
}
于 2012-07-04T07:23:36.730 に答える