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

问题描述

| 我编写了一个Secret Santa程序(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
非常感谢!     

解决方法

        我认为您的问题就在这里:
$giftfname[j],$fname[i] = $giftfname[i],$fname[j]
您的
i
值的范围在零到
$fname
(包括端值)中的最后一个索引之间,并且大概您的
$giftfname
作为
$fname
的克隆(或至少另一个相同长度的数组)开始。但是,当您旋转
each
时,您正在缩小
$giftfname
,因此
$giftfname[i]
将成为
nil
,并且上面的swap操作会将
nil
放入
$giftfname[j]
(这应该是
$giftfname
的有用项)。类似的问题适用于
$giftlname
$giftemail
。 我建议将一个数组与三个元素对象(名字,姓氏,电子邮件)一起使用,而不要使用三个并行数组。 Array上还有一个a15ѭ方法可能对您有用: 从众多的人开始。 复制该数组。 将副本随机播放,直到每个索引与原始数组都不同为止。 然后将
zip
在一起,以获得最终的送受者对列表。     ,        弄清楚了,并使用了retry语句。现在,if语句如下所示(所有其他变量也已被编辑为非全局变量)
if lname[i] == lname.last 
  santas = Array.new
  giftfname = fname.clone
  giftlname = lname.clone
  giftemail = email.clone
  retry  
除了进行其他一些编辑外,该方法还创建了我需要的解决方案,而又不会再次拆分太多代码。当然也可以尝试mu的解决方案,但是很高兴我现在可以无错运行了。