2017-07-25 17 views
0

它只計算一次每個單詞。我想讓它告訴我每個單詞出現多少次。我的Ruby計數器中的錯誤

dictionary = ["to","do","to","do","to","do"] 
string = "just do it to" 

def machine(word,list) 
    initialize = Hash.new 

    swerve = word.downcase.split(" ") 

    list.each do |i| 
     counter = 0 

     swerve.each do |j| 
      if i.include? j 
      counter += 1 
     end 
     end 
     initialize[i]=counter 
    end 
    return initialize 
    end 

machine(string,dictionary) 
+0

你有沒有考慮過使用包含多個單詞的測試字符串來嘗試它? – Hamms

+0

我剛剛做到了。它計數....但它是在計算我的字符串。世界背後是什麼? –

+2

當您舉一個例子時,您應該始終顯示所需的輸出。我真的不明白你想要做什麼。首先,由於您將第一個數組命名爲「dictionary」,因此我不希望它包含重複項。另外,返回值的格式應該是什麼?哈希,也許? –

回答

1

我假設,對於string中的每個單詞,您希望確定dictionary中該單詞的實例數。如果是這樣,第一步是創建一個計數散列

dict_hash = dictionary.each_with_object(Hash.new(0)) { |word,h| h[word] += 1 } 
    #=> {"to"=>3, "do"=>3} 

(我將在稍後解釋此代碼。)

現在拆分上空白string並創建一個哈希的鍵是字符串的話,其值的次數是的word值出現在dictionary

string.split.each_with_object({}) { |word,h| h[word] = dict_hash.fetch(word, 0) } 
    #=> {"just"=>0, "do"=>3, "it"=>0, "to"=>3} 

這當然假設string中的每個單詞都是唯一的。如果不是,根據所需的行爲,一種可能性是使用另一個計數散列。

string = "to just do it to" 
string.split.each_with_object(Hash.new(0)) { |word,h| 
    h[word] += dict_hash.fetch(word, 0) } 
    #=> {"to"=>6, "just"=>0, "do"=>3, "it"=>0} 

現在讓我來解釋一下上面的一些構造。

我使用類方法Hash::new的形式創建了兩個散列,它們的參數等於期望的默認值,這裏是零。這也就意味着,如果

h = Hash.new(0) 

h沒有一鍵等於價值word,然後h[word]將返回h的默認值(和哈希h不會改變)。在創建第一個散列之後,我寫了h[word] += 1。 Ruby將其擴展到

h[word] = h[word] + 1 

在她做任何進一步處理之前。傳遞給塊的string中的第一個字是"to"(它被分配給塊變量word)。由於哈希h是最初是空的(無鑰匙),h[word]上述等式的右邊返回默認值零,給我們

h["to"] = h["to"] + 1 
    #=> = 0 + 1 => 1 

後來,當word再次等於"to"默認值是沒有使用,因爲h現在有一個密鑰"to"

h["to"] = h["to"] + 1 
    #=> = 1 + 1 => 2 

我使用了很好的方法Enumerable#each_with_object。對於新手來說,這可能看起來很複雜。事實並非如此。行

dict_hash = dictionary.each_with_object(Hash.new(0)) { |word,h| h[word] += 1 } 

有效是相同如下。

h = Hash.new(0) 
dict_hash = dictionary.each { |word| h[word] += 1 } 
h 

換句話說,該方法允許一個編寫創建,構造並返回散列值,而不是三行做同樣的單行。

注意,我使用的方法Hash#fetch用於從散列檢索值:

dict_hash.fetch(word, 0) 

fetch的第二個參數(這裏0)被返回,如果dict_hash不具有相等的鍵的word值。相反,在這種情況下,dict_hash[word]返回nil

1「有效」的原因是當使用each_with_object時,變量h的作用域被限制在塊中,這通常是一種很好的編程習慣。如果您還沒有了解「範圍」,請不要擔心。

1

實際上,你可以做到這一點使用Array#count相當容易:

def machine(word,list) 
    word.downcase.split(' ').collect do |w| 
    # for every word in `word`, count how many appearances in `list` 
    [w, list.count { |l| l.include?(w) }] 
    end.to_h 
end 

machine("just do it to", ["to","do","to","do","to","do"]) # => {"just"=>0, "do"=>3, "it"=>0, "to"=>3} 
0
list.each do |i| 
     counter = 0 

     swerve.each do |j| 
      if i.include? j 
      counter += 1 

需要改變,以

swerve.each do |i| 
     counter = 0 

     list.each do |j| 
      if i.include? j 
      counter += 1 
0

你的代碼是告訴每個字多少次在字/字符串(包含在字典中的單詞)出現。 如果您想知道字典中每個單詞出現的次數,您可以切換list.each和swerve.each循環。然後,它會返回一個哈希#=> {「just」=> 0,「do」=> 3,「it」=> 0,「to」=> 3}

+0

我剛纔回答了我自己的問題,我會將其標記爲正確的。 –

+0

綠色選中標記的目的不是確認答案是「正確的」(有幾個可能是正確的),而是說「這個答案對我最有幫助」。爲此,您需要暫緩快速選擇,以便其他成員也可以發佈答案。 (快速選擇也可以阻止成員發佈其他答案。)沒有急於求成。許多人在等待至少幾個小時後才做出選擇;有些等待時間更長。 –

1

我認爲這就是你'重新尋找,但似乎你正在接近這個倒退

將您的字符串「字符串」轉換爲數組,刪除重複的值,並遍歷每個元素,計算數組「字典」中匹配的數量。可枚舉的方法:count在這裏很有用。

這裏輸出的一個好的數據結構是一個散列,其中我們將字符串「字符串」中的唯一字存儲爲鍵,並將這些字的出現次數存儲在數組「字典」中作爲值。哈希允許在一個集合中存儲關於數據的更多信息,而不是數組或字符串,所以這適合於這裏。

dictionary = [ "to","do","to","do","to","do" ] 

string = "just do it to" 

def group_by_matches(match_str, list_of_words) 

    ## trim leading and trailing whitespace and split string into array of words, remove duplicates. 

    to_match = match_str.strip.split.uniq 
    groupings = {} 

    ## for each element in array of words, count the amount of times it appears *exactly* in the list of words array. 
    ## store that in the groupings hash 

    to_match.each do | word | 
    groupings[ word ] = list_of_words.count(word) 
    end 

    groupings 
end 

group_by_matches(string, dictionary) #=> {"just"=>0, "do"=>3, "it"=>0, "to"=>3} 

在一個側面說明,你應該考慮使用更具描述性的變量和方法來幫助自己和他人遵循這是怎麼回事。

這也看起來像你有它倒退。通常,您希望使用該數組來計算字符串中出現的次數。這似乎更適合於一個真實世界的應用程序,您可以從預定義單詞列表中檢查數據的一個句子/字符串。

數組也很有用,因爲它們是靈活的數據集合,很容易迭代並通過枚舉方法進行變異。正如你所看到的,要處理字符串中的單詞,最簡單的辦法就是立即將它轉換爲一組單詞。

有很多選擇。如果你想縮短方法,你可以使用each_with_object調用或map調用來替換更詳細的每個循環,這將會返回一個新的對象,而不是每個對象的原始對象。在使用map.to_h的情況下,要小心to_h將在二維數組[["key1", "val1"], ["key2", "val2"]]上工作,但不在一維數組上。

## each_with_object 

def group_by_matches(match_str, list_of_words) 
    to_match = match_str.strip.split.uniq 

    to_match. 
    each_with_object({}) { | word, groupings | groupings[ word ] = list_of_words.count(word) } 
end 

## map 
def group_by_matches(match_str, list_of_words) 
    to_match = match_str.strip.split.uniq 

    to_match. 
    map { | word | [ word, list_of_words.count(word) ] }.to_h 
end 

根據性能,可讀性和可靠性測量您的方法首選項。