我想创建一个由类定义的对象(例如,狗),然后使用列表中的键填充哈希值,并将值作为这些对象。我试图这样做:
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)
- 最后我希望该哈希具有已存储名称的密钥spike
和spot
。每当我尝试使用myHash [' spike']。我得到的名字:
undefined method "name" for nil:NilClass (NoMethodError)
作为输出。
关于我做错什么的任何想法?
答案 0 :(得分:1)
您应该使用initialize
方法设置name
,然后使用map
和to_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"
至于修复方法,请使用=>
而不是:
,否则将block参数解释为符号:pupper
,并将其设置为哈希的键:< / p>
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 :(得分:0)
问题是:var: 42
和var => 42
符号存在巨大差异:
var = :foo
{var => 42}
#⇒ {:foo => 42}
,而
{var: 42}
#⇒ {:var => 42}
如果是key: value
表示法,key
被视为Symbol
且未展开,而key => value
则使用key
变量的实际值
此外,不是合并单个键值对,而是更明确地使用setter:
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
答案 2 :(得分:-1)
merge!
的参数应该是哈希值
myHash.merge!({pupper => tempObj})