这个代码从codefights发生了什么?

时间:2018-02-03 16:03:27

标签: ruby

我正在尝试阅读代码,但我并没有真正理解这一点。评论是我如何阅读此代码:

def firstDuplicate(a)
   counts = []                       #make an empty array named counts
   a.each do |value|                 #go through a
     return value if counts[value]   #a[0]: return 2 if counts[2]???
     counts[value] = true            #counts[2] = true???? wtf???
   end
   -1                                #return -1 if none of the above
 end 

这个问题来自codefights.com:

  

给定一个数组a,它只包含1到1之间的数字   a.length,找到第二个重复的第一个重复号码   发生具有最小指数。换句话说,如果还有更多   超过1个重复的数字,返回第二个数字   出现的索引小于另一个出现的索引   号码呢。如果没有这样的元素,return -1

     

实施例

     

对于a = [2, 3, 3, 1, 5, 2],输出应为firstDuplicate(a) = 3

     

有两个重复:数字2和3.第二次出现3   索引比第二次出现的索引小2,所以   答案是3。

     

对于a = [2, 4, 3, 5, 1],输出应为firstDuplicate(a) = -1

1 个答案:

答案 0 :(得分:2)

代码只是使用数组counts来跟踪以前是否看到过某个值。在这种情况下,代码可以像使用Hash一样轻松使用Array

考虑您的示例数组[2, 3, 3, 1, 5, 2]

在迭代数组之前,counts看起来像[] - 它是空的。

当我们开始迭代示例数组时,我们看到的第一个值是2。循环中的第一行代码检查counts[value]是否真实,但counts仍为空,因此counts[2]返回nil,这不是真的。我们向下移动到下一行并将counts[2]设置为truecounts现在看起来像是:[nil, nil, true]。 (数组为零索引,意味着第一个元素位于索引0,第二个元素位于索引1,第三个位于索引2,等等。)

现在,我们再次移动到循环的顶部并处理数组中的第二个值3counts[3]也是零(这是假的),所以我们还不能回来。因此,我们将counts[3]设置为true并返回到循环的顶部以处理数组中的下一个元素。现在counts看起来像是:[nil, nil, true, true]

现在我们处于数组中的第三个元素,这是另一个3

这一次,我们检查counts[3]以确定它是否真实。 counts仍然看起来像[nil, nil, true, true],因此counts[3]true。由于counts[3]为真,我们会返回3

如果在数组中没有找到重复值,那么我们将完成循环并最终到达-1的代码行。 Ruby方法返回方法中最后一行代码求值的值,在这种情况下为-1。因此,如果未找到重复项,我们会得到-1作为结果。