2

我想处理数组['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

4

4 回答 4

2

尝试这个

arr.each.with_index.with_object('') { |(each, n), obj| ... }

这是如何运作的?

  • 应用两者with_indexwith_object创建嵌套元组
  • (each, n), obj解包两个元组

有趣的事实——或者可能是相当可悲的事实——嵌套元组实际上是作为一个短暂的数组实现的,所以这将创建O(n)数组。如果这是一个关键的生产代码路径,我将不再嵌套这两个枚举函数。由于无论如何您很可能会分配obj给外部范围内的变量,因此将其重写为最有意义

obj = ''
arr.each_with_index { |each, n| ... }
于 2017-01-14T06:06:21.020 回答
2

它不使用您要求的方法,但可以完成工作并且相对紧凑:

array = ['a', 'b', 'c']
(0...array.size).zip(array).join
#=> "0a1b2c"
于 2017-01-14T10:50:16.833 回答
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

Or, if you still want to use each:

%w|a b c|.each.with_index.with_object('') do |char_idx, result|
  result << char_idx.join
end
于 2017-01-14T06:13:30.817 回答
0

这个解决方案很重要,这很好:

%w|a b c|.each_with_object('').with_index do |(char, result), i|
  result << "#{i}#{char}"
end

这里我们使用<<代替+=

with_object只适用于可变对象,你可能认为字符串是可变的,那为什么我们不能使用+=呢?因为+=等价于x = x+y,所以每次都会生成一个新对象。

最后,如果你使用+=with with_object,你永远不会改变你创建的原始对象,你只是创建一个新的对象,你不会在每次迭代时在块中跟踪。

更多细节在这里:each_with_object 应该如何工作?

于 2020-11-16T14:22:52.757 回答