Ruby 将散列值分配给对象的一种干燥方式
我正在寻找一种优雅的方法,将散列中存储的值分配到预先存在的对象中。 需要明确的是,如果我有一个对象,比如有两个属性的obj,比如name和age,我想分配这个来自散列的值,而不需要执行以下操作:Ruby 将散列值分配给对象的一种干燥方式,ruby,hash,Ruby,Hash,我正在寻找一种优雅的方法,将散列中存储的值分配到预先存在的对象中。 需要明确的是,如果我有一个对象,比如有两个属性的obj,比如name和age,我想分配这个来自散列的值,而不需要执行以下操作: obj.name = hash[:name] obj.age = hash[:age] 谢谢你的关注。 西蒙妮不知道优雅,但你可以做到: [:name, :age].each do |att| obj.send("#{att}=", hash[att]) end 最好的办法可能是简单地定义一个
obj.name = hash[:name]
obj.age = hash[:age]
谢谢你的关注。
西蒙妮不知道优雅,但你可以做到:
[:name, :age].each do |att|
obj.send("#{att}=", hash[att])
end
最好的办法可能是简单地定义一个方法,比如
update\u attributes
,它接受一个散列并在类的实例方法中执行
扩展其他人所写的内容以及您似乎需要的内容,我认为您最好的选择是:
hash.keys.each do |key|
m = "#{key}="
obj.send( m, hash[key] ) if obj.respond_to?( m )
end
这将说明:
- 没有始终在哈希中包含该类的所有属性,以及
- 散列中任意数量的键(不仅仅是:名称等)
实例变量集是另一种选择。以下是一个例子:
class Test; attr_accessor :name, :age; end
hash = {name: 'John', age: 52}
obj = Test.new
hash.each do |k,v|
obj.instance_variable_set("@#{k}".to_sym, v) # :name is converted to :@name
end
p obj # => #<Test:0x007fd8cbb75b00 @name="John", @age=52>
类测试;属性访问器:名称,:年龄;结束
哈希={name:'John',年龄:52}
obj=测试。新
hash.each do | k,v|
obj.instance_variable_set(“@#{k}.”to_sym,v)#:name转换为:@name
结束
p obj#=>#
唯一的诀窍是,实例变量集需要一个以@
开头的符号,因此:@name
是有效的,但:name
不是有效的。这里有一个我多年来一直使用的非常容易键入的模式:
{
first_name: "John",
last_name: "Smith",
...
}.each {|k, v| send("#{k}=", v)}
可以直接在对象上调用assign_attributes方法
obj.assign_attributes(hash)
如果hash.has_key?(attr)
,可能至少要在其中添加一个,以防hash中没有对象的所有属性。@thenduks:据我所知,该对象有两个属性,它们总是在hash中。但当然,这个问题的措辞并不准确。它应该至少有一个规范和一个测试套件需要正确回答。你的方法看起来很整洁,但你能解释一下正则表达式代表什么吗?@user442622:我想得到所有setter方法,即所有以等号结尾的方法(这是=$
部分),但是还有一些其他方法也以等号结尾(即==
,===
和!=
),所以我只匹配那些没有的方法
或=
作为它们的倒数第二个字符(这是[^!=]
部分)。你的方法看起来不错,但是如果我的名字和年龄都超过了怎么办?请你解释一下为什么你必须使用m=“{key}=”而不是m=“{key}”?这很难解释,但实际上很简单。首先,为了解释key
是字符串x
,hash[key]
是1
。。。现在,在Ruby中,代码obj.x=1
实际上相当于obj.x=(1)
。因此,在下一行中,当我执行obj.send(m…)
时,我需要将其分配给该属性。换句话说,如果我没有在方法名中添加等号,它会调用obj.x(1)
,并且x
根本不接受参数(因为它是一个属性)。我想要的是obj.x=(1)
这就是为什么我需要{key}=
你也可以这样做:hash.each do | key,value |
然后使用value
而不是hash[key]
。我会使用public\u send
@kode,听起来很合理,但多年来,我从未遇到过attr=
是私有的情况。这是一个活动记录特定的API,而不是Ruby标准库API。
obj.assign_attributes(hash)