2016-11-25 63 views
0

我有一個輸入數組的問題,嘗試在CodeWars上的Ruby挑戰。未定義的方法`split'for []:Array Ruby codewars「誰喜歡它?卡塔

以下是說明: 實現一個函數likes :: [String] - > String,它必須包含輸入數組,其中包含喜歡項目的人的姓名。它必須返回如例子中的顯示文本:

likes [] // must be "no one likes this" 
likes ["Peter"] // must be "Peter likes this" 
likes ["Jacob", "Alex"] // must be "Jacob and Alex like this" 
likes ["Max", "John", "Mark"] // must be "Max, John and Mark like this" 
likes ["Alex", "Jacob", "Mark", "Max"] // must be "Alex, Jacob and 2 others like this" 

我嘗試代碼是:

def likes(names) 
    arr = Array.[](names.split(/\W+/)) 
    if arr.size == 0 
    var = "no one likes this" 
    return var 
    elsif arr.size == 1 
    return arr[0]+ " likes this " 
    elsif arr.size == 2 
    return arr[0] + "and #{arr[1]} likes this " 
    elsif arr.size == 3 
    return " #{arr[0]}, #{arr[1]} and #{arr[2]} likes this " 
    elsif arr.size >3 
    return "#{arr[0]}, #{arr[1]} and #{arr.size-1} likes this " 
    end 
end 

而這正是編譯回報:

`likes': undefined method `split' for []:Array (NoMethodError) 
from `block in 
' 
from `block in describe' 
from `measure' 
from `describe' 
from ` 
' 

click to see image with error

+0

沒有名爲'split'爲陣的方法。 – vgoff

+0

通過@vgoff擴展評論:您已經將數組傳遞給方法。如果'names'是一個由名稱列表組成的字符串,那麼您需要使用'#split'將它分割成一個數組。但是由於'names'是一個數組,你可以簡單地消除包含'#split'方法的代碼行,並在整個方法中用'names'代替'arr'。 – moveson

+0

行結束符註釋以Ruby中的'#'開頭。 '//'不支持。 –

回答

1

這段代碼有很多混亂,需要在它開始工作之前解決。如果你想拉出一個數組的塊,你可以使用slice,或簡單的數組符號names[0,2],它提取前兩個。

當好奇您收到什麼樣的參數是經常添加一些代碼,找出簡單:

p names.class.inspect 

這將dump出來的東西,告訴你,你收到什麼樣的對象。在這種情況下,它是一個數組。

對於初學者來說,從代碼的角度來看,這太常見了,就像你在這裏測試特定數組長度的非常狹窄的情況一樣。真的只有三個條件:超過三個人,沒有人,和默認情況。

首先着眼於改變並獲得該權利的措辭:

def name_list(names) 
    if (names.empty?) 
    # An empty list means: 
    'nobody' 
    else 
    # Special case for the last element in the list, so pull it off 
    *names, last = names 

    # If there's more than two names remaining then change the 
    # phrasing of the last element to indicate "N others" 
    if (names.length > 2) 
     last = '%d others' % (names.length - 1) 
    end 

    # Join these together in the "X, Y, and Z" format. 
    (names[0,2] + [ 'and ' + last ]).join(', ') 
    end 
end 

有一些你可能做到這一點的方式,但是這是有分支的最低數量相當簡潔的方法。您希望避免重複自己,這就是錯誤的產生方式,並將常見行爲合併到通用代碼中。 「喜歡這個」部分就是這樣一個例子。如果你想改變措辭有一個地方做的

def likes(names) 
    name_list(names) + ' liked this' 
end 

這樣的話,你可以重新使用在你處理其他情況下,這種方法:

現在你可以做到這一點名字或事物的列表。

1

我會這樣寫。

def say_names(name_arr) 
    case name_arr.size 
    when 0 then "no one likes this" 
    when 1 then "%s likes this"   % name_arr 
    when 2 then "%s and %s like this"  % name_arr 
    when 3 then "%s, %s and %s like this" % name_arr 
    else "%s, %s and %d others like this" % (name_arr[0,2] + [name_arr.size-2]) 
    end 
end 

say_names [] 
    #=> "no one likes this" 
say_names ["Peter"] 
    #=> "Peter likes this" 
say_names ["Jacob", "Alex"] 
    #=> "Jacob and Alex like this" 
say_names ["Max", "John", "Mark"] 
    #=> "Max, John and Mark like this" 
say_names ["Alex", "Jacob", "Mark", "Max", "Trixie"] 
    #=> "Alex, Jacob and 3 others like this" 

雖然編寫方法可能稍短,但我喜歡這種方式。

0

使用你原來的代碼並添加一個簡單的三元表達

def likes(names) 
    arr = names.empty? ? [] : Array.[](names.split(/\W+/)) 
    if arr.size == 0 
    var = "no one likes this" 
    return var 
    elsif arr.size == 1 
    return arr[0]+ " likes this " 
    elsif arr.size == 2 
    return arr[0] + "and #{arr[1]} likes this " 
    elsif arr.size == 3 
    return " #{arr[0]}, #{arr[1]} and #{arr[2]} likes this " 
    elsif arr.size >3 
    return "#{arr[0]}, #{arr[1]} and #{arr.size-1} likes this " 
    end 
end 

應該做的伎倆。

更清晰的方法是刪除所有的返回語句,因爲ruby隱式返回最後一個評估對象。因此:

def likes(names) 
     arr = names.empty? ? [] : Array.[](names.split(/\W+/)) 
     if arr.size == 0 
     "no one likes this" 
     elsif arr.size == 1 
     arr[0]+ " likes this " 
     elsif arr.size == 2 
     arr[0] + "and #{arr[1]} likes this " 
     elsif arr.size == 3 
     "#{arr[0]}, #{arr[1]} and #{arr[2]} likes this " 
     elsif arr.size >3 
     "#{arr[0]}, #{arr[1]} and #{arr.size-1} likes this " 
     end 
    end 

最後,你可以把這個兩行,但你會犧牲可讀性這樣:

def likes(names) 
    arr = names.empty? ? [] : Array.[](names.split(/\W+/)) 
    arr.size == 0 ? "no one likes this" : arr.size == 1 ? arr[0]+ " likes this " : arr.size == 2 ? arr[0] + "and #{arr[1]} likes this" : arr.size == 3 ? "#{arr[0]}, #{arr[1]} and #{arr[2]} likes this " : "#{arr[0]}, #{arr[1]} and #{arr.size-1} likes this " 
end 
相關問題