如何用不同的变量限制每个`do`循环

时间:2018-01-04 04:19:47

标签: ruby loops each limit

我正在研究机器人。我有船,每个都放在一个数组my_ships。每艘船在创建时都会获得id,而不是创建它的人,每艘船都可以销毁。这是第一个数组:

ship = Ship.new(
  player_id, id,
  Float(x),
  Float(y),
  Integer(hp),
  Integer(status), 
  Integer(progress),
  Integer(planet)
)

每次迭代都会发送命令。我遇到了超时问题。我只有足够的时间跑~100。

如何限制each循环仅运行100次?

my_ships(0, 100).each do |ship|

让我减少使用的船只,因为有些船只被毁坏了,而且它们按照他们的身份命令。

2 个答案:

答案 0 :(得分:3)

假设在某种数据库中不存在这种情况,您应该使用数据库查询来选择和限制(因为没有标记与db相关的内容),您可以使用Enumerable#lazy(这是阵列的一个方法,因为数组是可枚举的)。您首先要只选择未销毁的船只,然后只选择其中的first 100艘:

my_ships.lazy.select do |ship|
  # Some logic to see if a ship is allowed to be iterated
end.first(100).each do |ship|
  # your loop that runs commands
end

如果更有意义,您可以使用reject代替select

my_ships.lazy.reject do |ship|
  # Some logic to see if a ship should not be iterated
end.first(100).each do |ship|
  # your loop that runs commands
end

为了更清楚地了解这将为您做些什么,请考虑以下示例:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
numbers.lazy.select do |number|
  puts "running check for #{number}"
  number.even?
end.first(2).each do |number|
  puts "doing something with #{number}"
end
# running check for 1
# running check for 2
# running check for 3
# running check for 4
# doing something with 2
# doing something with 4

所以在这个例子中,我想为前2个偶数运行一个循环......如果我只取前2个数字,我得到1个偶数和1个奇数;我也不想遍历整个列表,因为的检查是否均匀?可能很昂贵(不是,但你的支票可能是),或者你的列表可能很大,您只需要几个项目。这个循环足以让我得到符合我标准的前2个数字,然后让我在它们上面运行循环。

答案 1 :(得分:0)

根据@ {user3309314 comments中的建议,您可能希望使用next

arr = (1..100).to_a
enum = arr.to_enum

hun = loop.with_object [] do |_,o|
  if o.size == 10
    break o
  elsif enum.peek.even?
    o << enum.next
  else
    enum.next
  end
end

hun #=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

loop通过枚举遍历arr的每个元素,如果满足条件o,则将其添加到另一个数组even?break时的循环o.size == 10

可能更容易创建一个更明确的枚举器然后从中获取。这样你可以改变你需要的元素数量enum.take(8)获得前8个元素等。

enum = Enumerator.new do |y|
  arr = (1..100).to_a
  enum = arr.to_enum
  loop { enum.peek.even? ? y << enum.next : enum.next }
end

enum.take 10 #=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
相关问题