我需要为一些变量生成随机值。然后,如果这些值满足某些特征,我需要将它们丢弃并重新生成(重新定义变量的值?)。
我可能需要通过一个功能来完成这项任务,但我只是在学习这些并且不确定如何逃避这个地方"在函数中创建的变量(我稍后需要在脚本中调用它们)。
所以,让我说我有:
x = rand(1...9)
y = rand(1...9)
z = rand(1...9)
之后我需要像
这样的东西if x - y - z < 0
then **start over** until x - y - z > 0
end
这似乎必须有一个简单的&#34;解决方案,我只是没有经验/知识可以看到。任何想法都赞赏!
答案 0 :(得分:4)
编程中有许多模式,特别是Ruby,你会一次又一次地看到它们。这个 generate-and-verify-on-fail-redo 类型模式相当普遍,而且常见的Ruby具有begin ... end while (cond)
结构。
这里有一件对你不利的事情就是有三个变量。这违反了Zero, One or Infinity Rule,这对于组织代码至关重要。在处理超过“一”的事情时,请考虑使用类似数组的数据结构。
考虑到所有这些,这是一个简单的方法:
def random_values(count = 3)
begin
values = Array.new(count) { rand(1...9) }
end while (values.inject(&:-) <= 0)
values
end
这会一直生成列表,直到找到符合条件的列表。 inject
调用是通过迭代列表并从下一个元素中减去一个元素,然后在后续循环中使用该结果,对特定集合中的数字执行减法的快速方法。
Array
构造函数有两个参数,一个是预分配给它的元素数,第二个是定义如何生成这些元素的块。这是制作N长度随机值数组的快捷方法。
现在稍微更Ruby的方法是定义随机数集的生成器:
random_values = Enumerator.new do |y|
loop do
y << Array.new(3) { rand(1...9) }
end
end
这允许您将Enumerable库应用于问题,并find
符合您条件的第一个条目。在这里,您可以扩展此本地测试块中数组中的变量,以保持代码简单:
first = random_values.find do |x, y, z|
x - y - z > 0
end
这种方法的优点是你可以把事情连在一起并得到这样的东西:
selection = random_values.lazy.select do |x, y, z|
x - y - z > 0
end.first(10)
这将是“懒惰”枚举数组,即如果运行该循环直到完成它将按需生成它们,并将拉出匹配的前10个并将其保存在名为selection
的数组中。
答案 1 :(得分:0)
试试这个:
x = rand(1...9)
y = rand(1...9)
z = rand(1...9)
while x - y - z > 0
x = rand(1...9)
y = rand(1...9)
z = rand(1...9)
end
puts "x: #{x}, y: #{y}, z: #{z}"
更通用的方法可能是使用这样的方法:
def generate
x = rand(1...9)
y = rand(1...9)
z = rand(1...9)
[x,y,z]
end
x,y,z = generate()
while x - y - z > 0
x,y,z = generate()
end
puts "x: #{x}, y: #{y}, z: #{z}"