如何使用ruby更改小写的哈希键

时间:2013-06-08 12:20:23

标签: ruby hash lowercase

给出嵌套文档的哈希:

myHash = {
  "MemberId"=>"ABC0001", 
  "MemberName"=>"Alan", 
  "details"=>[
    {"LineNumber"=>"4.1", "Item"=>"A0001", "Description"=>"Apple"}, 
    {"LineNumber"=>"5.1", "Item"=>"A0002"}, 
    {"LineNumber"=>"6.1", "Item"=>"Orange"}
  ]
}

我想改变它,看起来像:

{
  "memberid"=>"ABC0001", 
  "membername"=>"Alan", 
  "details"=>[
    {"linenumber"=>"4.1", "item"=>"A0001", "description"=>"Apple"}, 
    {"linenumber"=>"5.1", "item"=>"A0002"}, 
    {"linenumber"=>"6.1", "item"=>"Orange"}
  ]
}

换句话说,我想在散列键中改为小写。 我知道我必须遍历哈希并使用 downcase 方法。如果在ruby中有这么简单的方法吗?

6 个答案:

答案 0 :(得分:5)

class Hash
  def downcase_key
    keys.each do |k|
      store(k.downcase, Array === (v = delete(k)) ? v.map(&:downcase_key) : v)
    end
    self
  end
end

myHash.downcase_key

答案 1 :(得分:3)

def f h
  Hash[h.map{|k,v| v.class == Array ? [k,v.map{|r| f r}.to_a] : [k.downcase,v]}]
end

proof

答案 2 :(得分:3)

我首先在Hash上创建一个方法,允许您将键映射到新值:

class Hash
  def map_keys! &blk
    keys.each do |k|
      new_k = blk.call(k)
      self[new_k] = delete(k)
    end
    self
  end

  def map_keys &blk
    dup.map_keys!(&blk)
  end
end

您现在可以使用

来缩小第一级
myHash.map_keys!(&:downcase)

myHash现在包含:

{"details"=>
  [{"LineNumber"=>"4.1", "Item"=>"A0001", "Description"=>"Apple"},
   {"LineNumber"=>"5.1", "Item"=>"A0002"},
   {"LineNumber"=>"6.1", "Item"=>"Orange"}],
 "memberid"=>"ABC0001",
 "membername"=>"Alan"}

可以使用

转换嵌套的哈希值
myHash['details'].each{|h| h.map_keys!(&:downcase) }

myHash现在包含:

{"details"=>
  [{"linenumber"=>"4.1", "item"=>"A0001", "description"=>"Apple"},
   {"linenumber"=>"5.1", "item"=>"A0002"},
   {"linenumber"=>"6.1", "item"=>"Orange"}],
 "memberid"=>"ABC0001",
 "membername"=>"Alan"}

答案 3 :(得分:1)

我今天在处理同样的问题时找到了这个解决方案。

def lowercase_keys(h)
  new_h = { }
  h.each_pair do |k, v|
    new_k = deep_lowercase(k, true)
    new_v = deep_lowercase(v, false)
    new_h[new_k] = new_v
  end
  new_h
end

def deep_lowercase(object, with_strings)
  case object
    when String then
      with_strings ? object.downcase : object
    when Hash then
      lowercase_keys(object)
    else
      object.respond_to?(:map) ? object.map { |e| deep_lowercase(e, false) } : object
  end
end

根据我的测试,无论Hash是值还是键本身,还是嵌入在Enumerable中,它都可以工作。

答案 4 :(得分:1)

您可以简单地做

hash.transform_keys(&:downcase)

将哈希键更改为小写。

您可以参考我的答案https://stackoverflow.com/a/54090178/8247133

答案 5 :(得分:0)

这是一个递归下降到任意嵌套的枚举的函数,并向它找到它找到的任何散列键:

data = {
  "MemberId"=>"ABC0001", 
  "MemberName"=>"Alan", 
  "details"=>[
    {"LineNumber"=>"4.1", "Item"=>"A0001", "Description"=>"Apple"}, 
    {"LineNumber"=>"5.1", "Item"=>"A0002"}, 
    {"LineNumber"=>"6.1", "Item"=>"Orange"}
  ]
}

def downcase_hash_keys(h)
  if h.is_a?(Hash)
    h.keys.each do |key|
      new_key = key.to_s.downcase
      h[new_key] = h.delete(key)
      downcase_hash_keys(h[new_key])
    end
  elsif h.respond_to?(:each)
    h.each { |e| downcase_hash_keys(e) }
  end
  h
end

downcase_hash_keys(data)
p data


# => {"memberid"=>"ABC0001", "membername"=>"Alan", "details"=>[{"linenumber"=>"4.1", "item"=>"A0001", "description"=>"Apple"}, {"linenumber"=>"5.1", "item"=>"A0002"}, {"linenumber"=>"6.1", "item"=>"Orange"}]}

它有点难看,因为它改变了数据结构;理想情况下,将创建一个新的哈希。但它达到了预期的效果。