无法将nil转换为字符串 - Ruby Secret Santa

时间:2011-06-21 22:16:07

标签: ruby arrays string null

我写了一个秘密圣诞老人程序(ala Ruby Quiz ... ish),但偶尔程序运行时,我收到一个错误。 统计:如果底池中有10个名字,则错误会在5%的时间内出现。如果底池中有100个名字,则不到1%。这是在bash上进行1000次试验。我已经确定礼品阵列在某些时候出现了零,但我不确定为什么或如何避免它。 提供代码...

0.upto($lname.length-1).each do |i|
  j = rand($giftlname.length) # should be less each time.
  while $giftlname[j] == $lname[i] # redo random if it picks same person
    if $lname[i] == $lname.last # if random gives same output again, means person is left with himself; needs to switch with someone
      $giftfname[j], $fname[i] = $giftfname[i], $fname[j]
      $giftlname[j], $lname[i] = $giftlname[i], $lname[j]
      $giftemail[j], $email[i] = $giftemail[i], $email[j]
    else
       j = rand($giftlname.length)
    end
  end
  $santas.push('Santa ' + $fname[i] + ' ' + $lname[i] + ' sends gift to ' + $giftfname[j] + ' ' + $giftlname[j] + ' at ' + '<' + $giftemail[j] + '>.') #Error here, something is sometimes nil
  $giftfname.delete_at(j)
  $giftlname.delete_at(j)
  $giftemail.delete_at(j)
end

非常感谢!

2 个答案:

答案 0 :(得分:1)

我认为你的问题就在这里:

$giftfname[j], $fname[i] = $giftfname[i], $fname[j]

您的i值介于0到$fname(包括)中的最后一个索引之间,大概是$giftfname作为$fname的克隆开始(或者至少另一个相同长度的数组)。但是,当您浏览each时,您正在缩小$giftfname,因此$giftfname[i]将为nil,上面的交换操作会将nil放入$giftfname[j] 1}}(应该是$giftfname的有用条目)。类似问题适用于$giftlname$giftemail

我建议使用一个包含三个元素对象(名字,姓氏,电子邮件)的数组,而不是三个并行数组。在Array上还有一个shuffle方法可能对您有用:

  • 从一群人开始。
  • 复制该数组。
  • 随机播放副本,直到与原始数组的每个索引不同。
  • 然后zip一起得到你的最终给号/接收器对列表。

答案 1 :(得分:0)

计算出来并使用重试语句。 if语句现在看起来像这样(所有其他变量也被编辑为非全局变量)

if lname[i] == lname.last 
  santas = Array.new
  giftfname = fname.clone
  giftlname = lname.clone
  giftemail = email.clone
  retry  

除了一些其他编辑之外,还创建了我需要的解决方案,而不会再次分解代码。肯定会尝试mu的解决方案,但我很高兴我现在没有这个错误运行。