如何在Ruby中分块数组

73
在Ruby 1.8.6中,我有一个由10万个用户ID组成的数组,每个ID都是整数。我想对这些用户ID执行一段代码,但是我想分批进行。例如,我想每次处理100个ID。如何尽可能简单地轻松实现这一点?
我可以像下面这样做,但可能会有更简单的方法:
a = Array.new
userids.each { |userid|
  a << userid
  if a.length == 100
    # Process chunk
    a = Array.new
  end
}
unless a.empty?
  # Process chunk
end

@Nakilon:那个问题不是比这个新吗? - Andrew Grimm
@Andrew Grimm,为了决定关闭哪个问题,我不是看日期,而是看答案的质量。我的意思是,我建议那些在这里寻找答案的人去那里寻找。 - Nakilon
就像Jon Skeet事实一样! - Andrew Grimm
2个回答

139

使用 each_slice 方法:

require 'enumerator' # only needed in ruby 1.8.6 and before
userids.each_slice(100) do |a|
  # do something with a
end

3
请注意,为使这个方法起作用,您实际上需要明确地“require 'enumerator'”:该方法在混入Enumerable的类中不可用,这最初让我认为此答案是错误的。后来我学到了更多知识。 - Mike Woodhouse
4
在1.8.6中,为了使这个工作正常(这也是我这样做的原因),你必须要求使用'enumerator'。 在1.8.7+中,enumerator已经移到核心部分,你不再需要要求它。然而,这样做不会导致错误,而只是返回false。因此,为了兼容性的原因,当使用enumerator的方法时,你应该始终要求'requirer enumerator',以便代码可以在所有版本的Ruby上工作。 - sepp2k
3
没错,在任何 Ruby 版本大于 1.8.6 的情况下都不需要它(就像我之前评论中提到的那样)。 - sepp2k

33

Rails有in_groups_of方法,它在底层使用each_slice

userids.in_groups_of(100){|group|
  //process group
}

3
我们不使用Rails。它无法满足我们的扩展需求;我们的数据库分散在大约26个分片上。此外,我们还有相当数量的其他数据库服务器,可能还有另外20个左右,尽管这些没有进行分片。谢谢你的建议,我相信对于许多其他人来说这将会很有用。 - ChrisInEdmonton
2
是的,我知道你没有使用Rails,所以我链接到了源代码,这样你就可以提取方法了。 - wombleton
而我为什么给你一个+1。 :) 因为这是一个好答案,虽然它可能不适用于我,但对其他人可能有帮助。 - ChrisInEdmonton
1
谢谢这个 - 当我查看 Rails 文档时,我错过了它。只是为了澄清最后一条评论,它在 Rails 3.x 中是可用的(文档)。另外,虽然有些晚了,但您可以在非 Rails 项目中包含 active_support,因为它是一个独立的 gem。 - theTRON

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接