如何限制块的调用次数?

And*_*imm 8 ruby block

使用gsub时如何限制替换次数?有人建议采用以下方式进行有限数量的替换:

str = 'aaaaaaaaaa'
count = 5
p str.gsub(/a/){if count.zero? then $& else count -= 1; 'x' end}
# => "xxxxxaaaaa"
Run Code Online (Sandbox Code Playgroud)

它可以工作,但代码混合了多少次替换(5)替换应该是什么("x",如果应该有替换,$&否则).有可能把这两个分开吗?

(如果在这种情况下很难将这两件事分开,但可以在其他一些场景中完成,将其作为答案发布)

ham*_*mar 8

如何将替换作为参数提取并通过在方法内使块关闭来封装计数器?

str = "aaaaaaaaaaaaaaa"

def replacements(replacement, limit)
    count = limit
    lambda { |original| if count.zero? then original else count -= 1; replacement end }
end

p str.gsub(/a/, &replacements("x", 5))
Run Code Online (Sandbox Code Playgroud)

您可以通过使用块替换来使其更加通用:

def limit(n, &block)
    count = n
    lambda do |original|
        if count.zero? then original else count -= 1; block.call(original) end
    end
end
Run Code Online (Sandbox Code Playgroud)

现在你可以做类似的事情了

p str.gsub(/a/, &limit(5) { "x" })
p str.gsub(/a/, &limit(5, &:upcase))
Run Code Online (Sandbox Code Playgroud)