2017-09-21 38 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其次阵列#排序的快捷方式,并认识到#每个散列上的散列值都与散列值相同(嵌套数组)。在这种情况下,您采用哪种方法并不重要。很显然,如果你需要按键进行迭代排序,那么你应该使用排序。