2016-08-23 125 views
0

我需要为几个变量生成随机值。然后,如果这些值符合某些特征,我需要将它们垃圾并重新生成(重新定义变量的值?)。生成,评估,然后在Ruby中重新生成随机数

我可能需要用一个函数来做到这一点,但我只是学习这些,并不知道如何逃避函数中创建的变量的“地点”(我需要稍后在脚本中调用它们)。

所以我们可以说我有:

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 

看起来这必须有一个“简单”的解决方案,我只是没有经验/知识见。任何想法赞赏!

+0

如果您发现任何有用的答案,请考虑选择一个您最喜欢的答案。 –

回答

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}" 
4

有一些编程模式和Ruby特别,你会看到时间和时间再次。这种类型模式是相当常见的,并且足够常见,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的数组中。

+0

为什么不使用'while values.inject(&:-) <= 0'? – pjs

+0

非常感谢tadman。那么,在脚本的后面,在这个函数之外,我可以从数组中调用这些值?即放置值[0]或放置值[0] +值[1]? –

+0

@pjs其实这是一个更好的做法,我会改变它。谢谢! – tadman