def upcase_every_so_many(str, freq)
return str if freq.zero?
str.gsub(/\p{L}/).with_index(1) { |c,i| (i % freq).zero? ? c.upcase : c }
end
str = "Now is the time for all good..."
puts "freq upcase_every_so_many(freq)"
(0..17).each { |freq| puts "%03s %020s" % [freq, upcase_every_so_many(str, freq)] }
freq upcase_every_so_many(freq)
0 Now is the time for all good...
1 NOW IS THE TIME FOR ALL GOOD...
2 NOw Is ThE tImE fOr AlL gOoD...
3 NoW is The TimE foR alL goOd...
4 Now Is thE timE for All gOod...
5 Now iS the tIme foR all gOod...
6 Now is The timE for alL good...
7 Now is tHe time fOr all goOd...
8 Now is thE time for All good...
9 Now is the Time for alL good...
10 Now is the tIme for all gOod...
11 Now is the tiMe for all gooD...
12 Now is the timE for all good...
13 Now is the time For all good...
14 Now is the time fOr all good...
15 Now is the time foR all good...
16 Now is the time for All good...
17 Now is the time for aLl good...
\p{L} 匹配每个 Unicode 字母。
请注意,我使用了String#gsub 的形式返回一个枚举器,并且我已将该枚举器链接到Enumerator#with_index。
这是该方法的一种变体。
def upcase_every_so_many(str, freq)
return str if freq.zero?
enum = ([false]*(freq-1) + [true]).cycle
str.gsub(/\p{L}/) { |c| enum.next ? c.upcase : c }
end
upcase_every_so_many(str, 4)
#=> "Now Is thE timE for All gOod..."
见Array#cycle。
对于freq = 4,
arr = [false]*(freq-1) << true
#=> [false, false, false, true]
enum = arr.cycle
#=> #<Enumerator: [false, false, false, true]:cycle>
enum.next
#=> false
enum.next
#=> false
enum.next
#=> false
enum.next
#=> true
enum.next
#=> false
... ad infinitum