2017-07-16 40 views
0

我想要创建一个由类定义的对象(例如,狗),然后使用列表中的键和来自这些对象的值填充散列。我试图做到这一点,像这样:将自定义对象放入哈希中

myHash = {} 
class Dog 
    attr_accessor :name, :weight 
end 

doglist = ['spike', 'spot'] 
doglist.each do |pupper| 
    tempObj = Dog.new 
    tempObj.name = pupper 
    myHash.merge!(pupper: tempObj) 

-at结束时,我会想这个hash,有钥匙spike且已存储的名称spot。每当我尝试使用myHash ['spike']。我得到: undefined method "name" for nil:NilClass (NoMethodError)作为输出。

任何想法,我做错了什么?

+0

你想你的最后的哈希看起来像什么? –

+0

如果我们使用的是我给出的例子,那么我的理想散列结果将如下所示: myHash = {'spike':<带名称的狗对象>, 'spot':<带名称的狗对象> } – sharp

回答

1

你或许应该使用initialize方法来设置name然后用mapto_h以创建哈希:

class Dog 
    attr_accessor :name, :weight 

    def initialize(name) 
    @name = name 
    end 
end 

doglist = ['spike', 'spot'] 

myHash = doglist.map {|k| [k, Dog.new(k)]}.to_h 
#=> {"spike" => #<Dog:0x00000001219ef8 @name="spike">, 
#  "spot" => #<Dog:0x00000001219e58 @name="spot"> } 

myHash['spike'].name #=> "spike" 

至于固定的方法,使用的:一个=>代替否则块参数被解释为符号:pupper并且将被设置为您的哈希键:

class Dog 
    attr_accessor :name, :weight 
end 

myHash = {} 
doglist = ['spike', 'spot'] 

doglist.each do |pupper| 
    tempObj = Dog.new 
    tempObj.name = pupper 
    myHash.merge!(pupper => tempObj) 
end 

myHash['spike'].name #=> "spike" 

作为旁注,在Ruby代码中使用两个空格进行缩进。

-1

merge !的参数应该是一个散列 myHash.merge!({pupper => tempObj})

+0

在'myHash.merge!(pupper:tempObj)'中,参数已经是一个完美的散列。 – mudasobwa

+0

当我用(pupper:tempObj)运行它时,它使用“pupper”(字符串)作为键而不是pupper的值。但是当我用箭头运算符(=>)运行它时,它使用pupper的值作为键。所以我想我应该说使用“=>”而不是“:”。 – pmcevoy12

+0

正确。对于'(pupper:tempObj)',它使用_not_不是'String',而是'Symbol'。 – mudasobwa

0

的事情是:存在var: 42var => 42符号剧烈的区别:

var = :foo 
{var => 42} 
#⇒ {:foo => 42} 

{var: 42} 
#⇒ {:var => 42} 

万一key: value表示法,key被处理作为Symbol且未扩展,而key => value使用key变量的实际值。

此外,而不是合并单一键值对,它更明确的使用二传手:

hash = {} 
hash[var] = 42 # better than hash.merge!(var => 42) 
#⇒ {:foo => 42} 

这就是说,下面的工作:

class Dog 
    attr_accessor :name, :weight 
end 

doglist = ['spike', 'spot'] 
doglist.each_with_object({}) do |pupper, acc| 
    acc[pupper] = Dog.new.tap { |dog| dog.name = pupper } 
    # or: 
    # dog = Dog.new 
    # dog.name = pupper 
    # acc.merge!(pupper => dog) 
end