![](/img/trans.png)
[英]Why am I getting NoMethodError undefined method for nil::NilClass
[英]Program working, but I'm still getting a NoMethodError 'length' nil
該程序采用兩個字符串數組,並從 a2 中的最短長度減去 a1 中最長的長度,然后反之亦然並返回較大的長度。
它有效(通過了 103/103 測試),但我收到此錯誤:
NoMethodError: undefined method `length' for nil:NilClass
main.rb:10:in `mxdiflg'
main.rb:66:in `block (2 levels) in <main>'
問題出在哪里? 由於這不是第一次發生這種情況,我該如何調試一個有效的程序?
def mxdiflg(a1, a2)
if a1 == '' || a2 == ''
-1
end
a1_order = a1.sort{|left, right| left.length <=> right.length}
a2_order = a2.sort{|left, right| left.length <=> right.length}
a_total = a1_order.reverse[0].length - a2_order[0].length
b_total = a2_order.reverse[0].length - a1_order[0].length
if b_total > a_total
b_total
else
a_total
end
end
從修復程序開始。 首先,您說您正在接受字符串數組,但是if a1 == '' || a2 == ''
if a1 == '' || a2 == ''
檢查您是否傳遞了空字符串。 放置-1
,而不是return -1
基本上沒有任何作用。
我假設錯誤在這一行(您main.rb:10:in 'mxdiflg'
有該行,它是main.rb:10:in 'mxdiflg'
因此第 10 行適合您):
a_total = a1_order.reverse[0].length - a2_order[0].length
就像您的數組為空一樣,您的array[0]
將為nil
因此您不能對其調用.length
(正如您粘貼的錯誤所提示的那樣)。
至於調試,在某些時候您將不得不習慣使用Pry ,但現在檢查行號和錯誤消息應該就足夠了。 在這種情況下,很明顯您在nil
上調用.length
,因此您的a1_order[0]
必須為nil
,因此您的數組必須為空。 您還可以添加簡單的 puts 消息,例如:
puts "a1_order: #{a1_order}"
puts "a2_order: #{a2_order}"
a_total = a1_order.reverse[0].length - a2_order[0].length
b_total = a2_order.reverse[0].length - a1_order[0].length
現在,在運行程序時,您可以檢查已排序的數組,應該很清楚您正在嘗試調用nil
的方法。
現在,有了這些,我們可以嘗試使您的程序更好一些。 首先,正如我提到的,你的第一張支票沒有多大意義。 讓我們把它變成:
return -1 if [a1,a2].any?(&:empty)
如果任何數組為空,它實際上將從您的方法返回-1
。
更進一步:
a1_order = a1.sort{|left, right| left.length <=> right.length}
可以寫成:
a1_order.sort_by(&:length)
打電話
a1_order.reverse[0]
有點低效,因為它會以相反的順序創建數組的副本,您可以簡單地執行a1_order.last
。
如果尋找最大值/最小值,您可以像這樣使用Enumerable#max_by /Enumerable#min_by :
a_total = a1.max_by(&:length).length - a2.min_by(&:length).length
b_total = a2.max_by(&:length).length - a1.min_by(&:length).length
使用Array#max可以獲得更高的值:
[a_total, b_total].max
將所有這些包裝在一起,您的方法可能如下所示:
def mxdiflg(a1, a2)
return -1 if [a1, a2].any?(&:empty?)
a_total = a1.max_by(&:length).length - a2.min_by(&:length).length
b_total = a2.max_by(&:length).length - a1.min_by(&:length).length
[a_total, b_total].max
end
問題之一是您如何檢查空數組。
irb(main):002:0> [] == ''
=> false
即使數組為空,也將始終返回 false。 空的? 是一種檢查空數組的方法,見下文。
#!/usr/bin/ruby
def run
p mxdiflg(["aa" , "b" , "c"], ["dddf", "r", "u", "ee"] )
p mxdiflg([], ["f", "r", "u", "ee"] )
end
def mxdiflg(a1, a2)
# return whatever you want if any of the arrays is empty
return false if a1.empty? || a2.empty?
# drop empty elements form array
a1.reject!(&:empty?)
a2.reject!(&:empty?)
a1_order = a1.sort{|left, right| left.length <=> right.length}
a2_order = a2.sort{|left, right| left.length <=> right.length}
a_total = a1_order.reverse[0].length - a2_order[0].length
b_total = a2_order.reverse[0].length - a1_order[0].length
(b_total > a_total) ? b_total : a_total
end
run
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.