如何通过不同的变量限制每个 `do` 循环
How to limit each `do` loop by a different variable
我正在开发一个机器人。我有船,每艘船都放在一个数组 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|
减少了我使用的船只,因为有些船只已被摧毁,而且它们是按 ID 排序的。
假设这不在某种数据库中,您应该在其中使用数据库查询 select 和限制(因为没有标记任何与数据库相关的内容),您可以使用 Enumerable#lazy
(this is a method on array's as well, since array's are Enumerable). You'll first want to select only the ships that are not destroyed and then take only the 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
instead of 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 个奇数;我也不想遍历整个列表,因为检查 is this even? 可能很昂贵(不是,但你的检查可能是),或者你的列表可能是大,你只需要几件物品。这个循环足以让我找到符合我标准的前 2 个数字,然后让我 运行 我对它们进行循环。
正如@user3309314 在 中的建议,您可能希望使用 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
的每个元素,如果满足条件even?
,则将其添加到另一个数组o
。当 o.size == 10
.
时循环 break
s
创建一个更明确的枚举器然后从中获取可能更容易。这样你就可以改变你需要多少元素 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]
我正在开发一个机器人。我有船,每艘船都放在一个数组 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|
减少了我使用的船只,因为有些船只已被摧毁,而且它们是按 ID 排序的。
假设这不在某种数据库中,您应该在其中使用数据库查询 select 和限制(因为没有标记任何与数据库相关的内容),您可以使用 Enumerable#lazy
(this is a method on array's as well, since array's are Enumerable). You'll first want to select only the ships that are not destroyed and then take only the 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
instead of 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 个奇数;我也不想遍历整个列表,因为检查 is this even? 可能很昂贵(不是,但你的检查可能是),或者你的列表可能是大,你只需要几件物品。这个循环足以让我找到符合我标准的前 2 个数字,然后让我 运行 我对它们进行循环。
正如@user3309314 在 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
的每个元素,如果满足条件even?
,则将其添加到另一个数组o
。当 o.size == 10
.
break
s
创建一个更明确的枚举器然后从中获取可能更容易。这样你就可以改变你需要多少元素 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]