为什么我不能让Array#slice以我想要的方式工作?

时间:2014-08-19 22:27:02

标签: ruby activerecord

我有一个很大的Array AR模型实例。我们假设阵列中有20K个条目。我希望每次在这个数组中移动1000个块。

slice_size = 1000
start = 0
myarray.slice(start, slice_size) do |slice|
  slice.each do |item|
    item.dostuff
  end
  start+=slice_size
end

我可以用以下内容替换整个内部块:

puts "hey"

并且在控制台中看不到任何东西。我从周日开始尝试这9种方式。我之前已成功完成,只是不记得在哪里。 And I have RTFM.任何人都可以提供帮助吗?

3 个答案:

答案 0 :(得分:2)

问题是slice没有阻塞,但你传递了一个块,并试图在其中做一些事情,这被忽略了。如果你这样做

myarray.slice(start, slice_size).each do |slice|
  ...
end

然后它应该工作。

但这样做不是Ruby-ish。更好的方法是

myarray.each_slice(slice_size) do |slice|
  ...
end

答案 1 :(得分:1)

如果阵列可以被销毁,你可以这样做:

((myarray.size+slice_size-1)/slice_size).times.map {myarray.shift(slice_size)}

如果不是:

((myarray.size+slice_size-1)/slice_size).times.map { |i|
  myarray.slice(i*slice_size, slice_size) }

答案 2 :(得分:0)

您可以使用:

  • Enumerable#each_slice(n),一次只收n项;
  • Array#in_groups_of(n)(如果这是Rails)就像each_slice一样,但会填充最后一组以保证组大小保持不变;

但我建议使用ActiveRecord的内置Model.find_each,它会在数据库层中批量查询以获得更好的性能。它默认为1000,但您可以指定批量大小。有关详细信息,请参阅http://guides.rubyonrails.org/active_record_querying.html#retrieving-multiple-objects-in-batches

指南中的示例:

User.find_each(batch_size: 5000) do |user|
  NewsLetter.weekly_deliver(user)
end