-1

我经常需要在循环中做一些操作,在迭代之间做一些其他操作。一个简单的例子是将数组中的单词收集成一个字符串,向后拼写并用逗号分隔。是否有任何语言的成语或语言支持?(现在我对 Ruby 最感兴趣。)

我通常会做类似的事情

a = ['foo', 'bar', 'baz']
s = ''
n = a.size - 1
i = 0
loop do
  s << a[i].reverse
  break if i == n
  s << ', '
  i += 1
end

但是如果使用 ruby​​ 迭代器,我不知道保存这个半迭代的好方法。

这看起来是多余的:

a = ['foo', 'bar', 'baz']
s = ''
a.each do |w|
  s << w.reverse
  s << ', ' unless w == a.last
end

更新 1.一个更实际的示例是创建一个 Haml 模板,其中 HTML 块是在循环中创建的,并且需要与其他 HTML 块连接。


更新 2.programmers.stackexchange上,有人建议我的问题被称为“循环半”问题。


更新 3.我无法在 Haml 中应用 Map-Reduce 模式,因为 Haml 不允许关闭块end(它只使用缩进),所以我找不到链接mapreduce. 所以从某种意义上说,这个问题仍然是开放的,但也许它也是封闭的,因为没有办法做到这一点。所以这是一个悬而未决的问题,我猜。

4

5 回答 5

4

标准的 Ruby 方式是:

a.map(&:reverse).join(", ")
于 2013-02-26T20:59:33.693 回答
2

您已经区分了数组中每个元素的处理和以某种方式转换结果数组的其他处理。这些是 MapReduce 模型中的“map”和“reduce”。

http://en.wikipedia.org/wiki/Mapreduce

于 2013-02-26T21:45:24.250 回答
0
a = ['foo', 'bar', 'baz'] 
a.each do |w|
    w.reverse!
end
s = a.join(',')

这是你要找的吗?输出是:

oof,rab,zab

于 2013-02-26T21:00:56.837 回答
0

如果您需要经常执行这样的操作,您可以轻松扩展Array

class Array
  def join_cb
    inject ('') { |v, e| 
      v += "#{e}#{yield e unless e == self.last}"
    }
  end
end

并像这样使用它:

> a = ['foo', 'bar', 'baz']
> a.map(&:reverse).join_cb { '%' }
# ⇒ "oof%rab%zab"

或者,使 concat 字符串依赖于数组元素:

> a.map(&:reverse).join_cb { |e| e == 'rab' ? '-' : '_' }
# ⇒ "oof_rab-zab"
于 2013-02-26T22:26:44.233 回答
0

作为即使在 Haml 中也有效的解决方案,建议我执行以下操作:

a.each_with_index do |item, index|
  unless index.zero?
    # do what is to be done between the iterations
  end
  # do what is to be done on all iterations
end

我现在正在使用它,但它当然不是最优的:条件在每次迭代时运行。作为一个小小的不便,前一个项目在“迭代之间”是不可访问的。

于 2013-03-02T12:22:09.430 回答