我想处理数组['a', 'b', 'c']
以返回字符串'0a1b2c'
(即通过将每个索引与其值连接而形成的字符串)。
我可以这样做:
result = ''
['a', 'b', 'c'].each.with_index do |char, i|
result += "#{i}#{char}"
end
result
我想使用with_object消除块外的结果变量。
这样的事情:
['a', 'b', 'c'].each.with_index.with_object('') do |char, i, result|
result += "#{i}#{char}"
end
但这会引发错误undefined method '+' for nil:NilClass
答案 0 :(得分:2)
试试这个
arr.each.with_index.with_object('') { |(each, n), obj| ... }
这是如何运作的?
with_index
和with_object
会创建嵌套元组(each, n), obj
解包两个元组有趣的事实 - 或者可能相当悲伤的事实 - 嵌套元组实际上被实现为一个短命数组,因此这将创建O(n)
数组。如果这是一个关键的生产代码路径,我将把这两个枚举函数嵌套。因为你最有可能将obj
分配给外部范围中的变量,所以将其重写为
obj = ''
arr.each_with_index { |each, n| ... }
答案 1 :(得分:2)
它没有使用你要求的方法,但它完成了工作并且相对紧凑:
array = ['a', 'b', 'c']
(0...array.size).zip(array).join
#=> "0a1b2c"
答案 2 :(得分:1)
两个操作都应该在不滥用each
迭代器:
%w|a b c|.map.with_index do |char, i|
"#{i}#{char}"
end.join
%w|a b c|.each_with_object('').with_index do |(char, result), i|
result << "#{i}#{char}"
end
或者,如果您仍想使用每个:
%w|a b c|.each.with_index.with_object('') do |char_idx, result|
result << char_idx.join
end
答案 3 :(得分:0)
此解决方案很重要,这很不错:
%w|a b c|.each_with_object('').with_index do |(char, result), i|
result << "#{i}#{char}"
end
在这里,我们使用<<
代替+=
。
with_object
仅适用于可变对象,您可能会认为该字符串是可变的,那么为什么我们不能使用+=
?因为+=
等效于x = x+y
,所以它每次都会生成一个新对象。
最后,如果您将+=
与with_object
一起使用,则永远不会突变您创建的原始对象,而只是创建一个新对象,您将不会在每次迭代时在该块中进行跟踪