簡體   English   中英

程序正在運行,但我仍然收到 NoMethodError 'length' nil

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM