我建议如下。
def do_magic(letters)
length = letters.size
letters.downcase.each_char.with_index.with_object([]) { |(letter, i), new_letters|
new_letters << (letter * (length - i)).capitalize }.join
end
do_magic 'teSt'
# => "TtttEeeSsT"
让我们完成这些步骤。
letters = 'teSt'
length = letters.size
#=> 4
str = letters.downcase
#=> "test"
enum0 = str.each_char
#=> #<Enumerator: "test":each_char>
enum1 = enum0.with_index
#=> #<Enumerator: #<Enumerator: "test":each_char>:with_index>
enum2 = enum1.with_object([])
#=> #<Enumerator: #<Enumerator: #<Enumerator: "test":each_char>:
# with_index>:with_object([])>
仔细检查创建枚举器enum0、enum1 和enum2 的返回值。后两者可以被认为是复合枚举数。
第一个元素由enum2(enum2.next 的值)生成,块变量使用消歧(又名分解)赋值。 p>
(letter, i), new_letters = enum2.next
#=> [["t", 0], []]
letter
#=> "t"
i #=> 0
new_letters
#=> []
然后执行块计算。
m = letter * (length - i)
#=> "tttt"
n = m.capitalize
#=> "Tttt"
new_letters << n
#=> ["Tttt"]
下一个元素由enum2生成,传递给block并进行block计算。
(letter, i), new_letters = enum2.next
#=> [["e", 1], ["Tttt"]]
letter
#=> "e"
i #=> 1
new_letters
#=> ["Tttt"]
注意new_letters 是如何更新的。分块计算如下。
m = letter * (length - i)
#=> "eee"
n = m.capitalize
#=> "Eee"
new_letters << n
#=> ["Tttt", "Eee"]
enum2 的最后两个元素生成后,我们有
new_letters
#=> ["Tttt", "Eee", "Se", "T"]
最后一步是将new_letters的元素组合成一个字符串。
new_letters.join
#=> "TtttEeeSeT"