我有一个看起来像这样的哈希:
card = {
name: "Mrs.Jones",
number: "4242 4242 4242 4242",
exp_month: "12",
exp_year: "2014",
address: "90210 Beverly Hills",
added: "2014-11-09 09:14:23"
}
我想迭代number
,exp_month
和exp_year
字段并更新它们。什么是最像Ruby的方式呢?
这就是我目前的代码:
card.each do |key,value|
card[key] = encrypt(value) # Only apply to number, exp_month and exp_year
end
答案 0 :(得分:3)
我会按照以下方式进行:
ENCRYPTED_FIELDS = [:number, :exp_month, :exp_year]
card.each do |key,value|
card[key] = encrypt(value) if ENCRYPTED_FIELDS.include?(key)
end
但更好的选择是为CreditCardDetails创建一个类并定义加密数据的setter:
class CreditCardDetails
def initialize(hash)
hash.each do |k, v|
self.send("#{k}=", v)
end
end
#example for not encrypted field
def name=(value)
@name = value
end
#example for encrypted field
def number=(value)
@number = encrypted(value)
end
end
答案 1 :(得分:2)
由于您已经知道要加密哪些密钥,因此可以迭代所需的密钥名称,而不是哈希:
ENCRYPTED_FIELDS = [:number, :exp_month, :exp_year]
ENCRYPTED_FIELDS.each do |key|
card[key] = encrypt(card[key])
end
答案 2 :(得分:1)
以下是一些方法。为了便于说明,我已将方法encrypt
替换为size
。它们都使用了Hash#merge的形式。第二种方法不使用密钥。相反,如果值是所有数字(和空格),它将处理该值。我把它包括在内主要是为了说明你在其他应用程序中可能会做些什么。
<强>#1 强>
card.merge(card) do |k,_,v|
case k
when :number, :exp_month, :exp_year
v.size
else
v
end
end
#=> {:name=>"Mrs.Jones", :number=>19, :exp_month=>2, :exp_year=>4,
# :address=>"90210 Beverly Hills", :added=>"2014-11-09 09:14:23"}
<强>#2 强>
card.merge(card) { |*_,v| v[/^[\s\d]+$/] ? v.size : v }
#=> {:name=>"Mrs.Jones", :number=>19, :exp_month=>2, :exp_year=>4,
# :address=>"90210 Beverly Hills", :added=>"2014-11-09 09:14:23"}
如果您想要改变card
,请使用Hash#update(a.k.a。merge!
)而不是merge
:
<强>#1A 强>
card.update(card) do |k,_,v|
case k
when :number, :exp_month, :exp_year
v.size
else
v
end
end
#=> {:name=>"Mrs.Jones", :number=>19, :exp_month=>2, :exp_year=>4,
# :address=>"90210 Beverly Hills", :added=>"2014-11-09 09:14:23"}
card
#=> {:name=>"Mrs.Jones", :number=>19, :exp_month=>2, :exp_year=>4,
# :address=>"90210 Beverly Hills", :added=>"2014-11-09 09:14:23"}