程序运行正常,但我仍然收到 NoMethodError 'length' nil
Program working, but I'm still getting a NoMethodError 'length' nil
这个程序取两个字符串数组,用a2中最短的字符串减去a1中最长的字符串的长度,然后反之亦然returns较大的。
有效(通过了 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 == ''
检查您是否传递了空字符串。输入 -1
而不是 return -1
基本上什么都不做。
我假设错误出在这一行(堆栈跟踪中有这一行,它是 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 "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
实际上会从您的方法中 return。
更进一步:
a1_order = a1.sort{|left, right| left.length <=> right.length}
可以写成:
a1_order.sort_by(&:length)
正在调用
a1_order.reverse[0]
有点低效,因为它会以相反的顺序创建数组的副本,你可以简单地做 a1_order.last
来代替。
如果要查找 maximum/minimum 值,您可以像这样使用 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
将始终 return 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
这个程序取两个字符串数组,用a2中最短的字符串减去a1中最长的字符串的长度,然后反之亦然returns较大的。
有效(通过了 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 == ''
检查您是否传递了空字符串。输入 -1
而不是 return -1
基本上什么都不做。
我假设错误出在这一行(堆栈跟踪中有这一行,它是 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 "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
实际上会从您的方法中 return。
更进一步:
a1_order = a1.sort{|left, right| left.length <=> right.length}
可以写成:
a1_order.sort_by(&:length)
正在调用
a1_order.reverse[0]
有点低效,因为它会以相反的顺序创建数组的副本,你可以简单地做 a1_order.last
来代替。
如果要查找 maximum/minimum 值,您可以像这样使用 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
将始终 return 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