2017-09-21 39 views
1

我是ruby的新手,我正在解決一個涉及哈希和密鑰的問題。該問題要求我實現一個接受散列作爲參數的方法#pet_types。哈希使用人們的#名稱作爲關鍵字,並且這些值是該人擁有的寵物類型的數組。我的問題是關於使用Hash#每個方法遍歷數組中的每個數字。我想知道在使用hash#each或hash.sort.each解決問題之間是否有區別? 我花了幾個小時提出了不同的解決方案,仍然找出解決以下問題的兩種方法之間有什麼不同的方法。關於在ruby中實現哈希的問題

我包括我的代碼在repl.it:https://repl.it/H0xp/6或者你可以看到如下:

# Pet Types 
# ------------------------------------------------------------------------------ 
# Implement a method, #pet_types, that accepts a hash as an argument. The hash uses people's 
# names as keys, and the values are arrays of pet types that the person owns. 

# Example input: 
# { 
# "yi" => ["dog", "cat"], 
# "cai" => ["dog", "cat", "mouse"], 
# "venus" => ["mouse", "pterodactyl", "chinchilla", "cat"] 
# } 
def pet_types(owners_hash) 

    results = Hash.new {|h, k| h[k] = [ ] } 
    owners_hash.sort.each { |k, v| v.each { |pet| results[pet] << k } } 
    results 
end 

puts "-------Pet Types-------" 

owners_1 = { 
    "yi" => ["cat"] 
} 
output_1 = { 
    "cat" => ["yi"] 
} 

owners_2 = { 
    "yi" => ["cat", "dog"] 
} 
output_2 = { 
    "cat" => ["yi"], 
    "dog" => ["yi"] 
} 

owners_3 = { 
    "yi" => ["dog", "cat"], 
    "cai" => ["dog", "cat", "mouse"], 
    "venus" => ["mouse", "pterodactyl", "chinchilla", "cat"] 
} 
output_3 = { 
    "dog" => ["cai", "yi"], 
    "cat" => ["cai", "venus", "yi"], 
    "mouse" => ["cai", "venus"], 
    "pterodactyl" => ["venus"], 
    "chinchilla" => ["venus"] 
} 


    # method 2 
    # The 2nd and 3rd method should return a hash that uses the pet types as keys and the values should 
    # be a list of the people that own that pet type. The names in the output hash should 
    # be sorted alphabetically 

    # switched_hash = Hash.new() 

    # owners_hash.each do |owner, pets_array| 
    # pets_array.each do |pet| 
    #  select_owners = owners_hash.select { |owner, pets_array| 

owners_hash[owner].include?(pet) } 

    #  switched_hash[pet] = select_owners.keys.sort 
    # end 
    # end 

    # method 3 
    #switched_hash 
    # pets = Hash.new {|h, k| h[k] = [ ] } # WORKS SAME AS: pets = Hash.new(Array.new) 
    # owners = owners_hash.keys.sort 
    # owners.each do |owner| 
    # owners_hash[owner].each do |pet| 
    #  pets[pet] << owner 
    # end 
    # end 
    # pets 
# Example output: 

# output_3 = { 
# "dog" => ["cai", "yi"], 
# "cat" => ["cai", "venus", "yi"], ---> (sorted alphabetically!) 
# "mouse" => ["cai", "venus"], 
# "pterodactyl" => ["venus"], 
# "chinchilla" => ["venus"] 
# } 

我在程序中使用的散列數據結構首先解決這個問題。然後我試着用pet_hash重寫它。而我的最終代碼如下:

def pet_types(owners_hash) 
    pets_hash = Hash.new { |k, v| v = [] } 

    owners_hash.each do |owner, pets| 
    pets.each do |pet| 
     pets_hash[pet] += [owner] 
    end 
    end 


    pets_hash.values.each(&:sort!) 

    pets_hash 
end 

puts "-------Pet Types-------" 
owners_1 = { 
    "yi" => ["cat"] 
} 
output_1 = { 
    "cat" => ["yi"] 
} 
owners_2 = { 
    "yi" => ["cat", "dog"] 
} 
output_2 = { 
    "cat" => ["yi"], 
    "dog" => ["yi"] 
} 
owners_3 = { 
    "yi" => ["dog", "cat"], 
    "cai" => ["dog", "cat", "mouse"], 
    "venus" => ["mouse", "pterodactyl", "chinchilla", "cat"] 
} 
output_3 = { 
    "dog" => ["cai", "yi"], 
    "cat" => ["cai", "venus", "yi"], 
    "mouse" => ["cai", "venus"], 
    "pterodactyl" => ["venus"], 
    "chinchilla" => ["venus"] 
} 
puts pet_types(owners_1) == output_1 
puts pet_types(owners_2) == output_2 
puts pet_types(owners_3) == output_3 
+0

我測試了代碼,並且每個方法都通過了測試。 – DataEngineer

回答

2

散列#排序有同樣的效果(至少我的基本測試)作爲哈希#to_a其次陣列#排序。

hash = {b: 2, a: 1} 
hash.to_a.sort # => [[:a, 1, [:b, 2]] 
hash.sort  # => the same 

現在我們來看看#each,它們都在Hash和Array上。

當您向塊提供兩個參數時,它可以處理這兩種情況。對於散列,第一個參數將是關鍵字,第二個參數是值。對於嵌套數組,該值基本上得到splatted出到ARGS:

[[:a, 1, 2], [:b, 3, 4]].each { |x, y, z| puts "#{x}-#{y}-#{z}" } 
# => a-1-2 
# => b-3-4 

因此,基本上,你應該考慮的Hash#排序是散列#to_a其次陣列#排序的快捷方式,並認識到#每個散列上的散列值都與散列值相同(嵌套數組)。在這種情況下,您採用哪種方法並不重要。很顯然,如果你需要按鍵進行迭代排序,那麼你應該使用排序。