繁体   English   中英

遍历Ruby中哈希的一些元素

[英]Iterate over just some elements of a Hash in Ruby

我有一个看起来像这样的哈希:

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"
}

我只想遍历numberexp_monthexp_year字段并更新它们。 最像Ruby的方式是什么?

这是我的代码目前的样子:

card.each do |key,value|
  card[key] = encrypt(value) # Only apply to number, exp_month and exp_year
end

我将通过以下方式进行操作:

ENCRYPTED_FIELDS = [:number, :exp_month, :exp_year]

card.each do |key,value|
  card[key] = encrypt(value) if ENCRYPTED_FIELDS.include?(key)
end

但是更好的选择是为CreditCardDetails创建一个类并定义设置器以加密数据:

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

由于您已经知道要加密的密钥,因此可以遍历所需的密钥名称,而不是哈希:

ENCRYPTED_FIELDS = [:number, :exp_month, :exp_year]

ENCRYPTED_FIELDS.each do |key|
  card[key] = encrypt(card[key])
end

这有两种方法。 为了说明起见,我用size替换了encrypt方法。 它们都使用带一个块的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 (又名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"}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM