ruby - Program working, but I'm still getting a NoMethodError 'length' nil
问题描述
This program takes two arrays of strings and subtracts the length of the longest in a1 from the shortest in a2, and then vice-versa and returns the greater.
It works (passed 103/103 tests), but I'm getting this error:
NoMethodError: undefined method `length' for nil:NilClass
main.rb:10:in `mxdiflg'
main.rb:66:in `block (2 levels) in <main>'
Where's the issue? And since this isn't the first time this has happened, how do I debug a program that works?
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 == ''
检查您是否传递了空字符串。放-1
, not areturn -1
基本上什么都不做。
我假设错误在这一行中(你在stacktrace中有这一行,main.rb:10:in 'mxdiflg'
因此它是你的第10行):
a_total = a1_order.reverse[0].length - a2_order[0].length
好像你的数组是空的,你的array[0]
意志是这样的,nil
所以你不能调用.length
它(就像你粘贴的错误所说的那样)。
至于调试,在某些时候您将不得不熟悉使用Pry,但现在检查行号和错误消息就足够了。在这种情况下,很明显您正在调用.length
a nil
,因此您的a1_order[0]
must be 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
s 上的方法。
现在,有了这些,我们可以尝试使您的程序更好一些。首先,正如我所提到的,您的第一次检查没有多大意义。让我们把它变成:
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
推荐阅读
- android - Android 返回错误的设备宽度
- git - 我们应该将 Master 合并到 Release 还是相反?
- python - 按值和位置替换 Numpy 数组中的元素
- azure - 尝试使用 Microsoft Graph API 创建消息草稿时出错
- groovy - NiFi ExecuteScript 处理器中的 Groovy 异常未调用 Catch 块
- linux - Yocto - 无法执行调试包
- ios - Xcode 加载配置文件失败
- python - 使用熊猫,如何从中点生成垃圾箱?
- python - Levenshtein 距离 igonore 悬垂碱基
- git - Windows 上的 Git——所有 Git 客户端都使用相同的配置堆栈,对吗?