transform_keys表示哈希数组

时间:2017-02-17 20:47:59

标签: ruby-on-rails ruby hash key transform

我有以下哈希数组,我想使用transform_keys使用正则表达式去除每个键的开头:

transformed_hash_keys = [{"abc"=>"1",  
 "def"=>"1",  
 "hij"=>"1",},  
{"abc"=>"2",  
 "def"=>"2",  
 "hij"=>"2"}]  

我想要以下内容:

def strip  
    s = array_of_hashes.each { |hash| hash.transform_keys { |key| key.sub(/^a_(\d+)_/, '') } }  
end

我有以下方法,但它导致array_of_hashes而不是transformed_hash_keys:

2017-01-12T17:23:14.000-0800

有谁能告诉我这个方法我做错了什么?

3 个答案:

答案 0 :(得分:1)

"hereis-SSN1234_12-12" -->"SSN1234_12" "from-SSN2343_SSN3223-21" --> "SSN2343_SSN3223" "SSN1235_SSN021_SSN3122-123" --> "SSN1235_SSN021_SSN3122" "here: SSN1_SSN022_SSN3223_SSN9233-323" --> "SSN1_SSN022_SSN3223_SSN9233" 无法就地运行,transform_keys会返回原始迭代器,而不是块的结果。

您可以使用each代替map来执行您想要的操作。

each

或者,您可以使用def strip s = array_of_hashes.map { |hash| hash.transform_keys { |key| key.sub(/^a_(\d+)_/, '') } } end 修改transform_keys!

的内容
array_of_hashes

答案 1 :(得分:1)

这是一个纯Ruby解决方案。

arr = [{ "a_0_abc"=>"1", "a_0_def"=>"1", "a_0_hij"=>"1" },
       { "a_1_abc"=>"2", "a_1_def"=>"2", "a_1_hij"=>"2" }]

arr.map { |h| h.map { |k,v| [k[/[[:alpha:]]+\z/], v] }.to_h }
  #=> [{"abc"=>"1", "def"=>"1", "hij"=>"1"}, {"abc"=>"2", "def"=>"2", "hij"=>"2"}] 

arr.map { |h| h.each_with_object({}) { |(k,v),g| g[k[/[[:alpha:]]+\z/]] = v } }
  # => [{"abc"=>"1", "def"=>"1", "hij"=>"1"}, {"abc"=>"2", "def"=>"2", "hij"=>"2"}] 

答案 2 :(得分:0)

这使您可以对键进行任何类型的转换,只需将块传递给它即可:

def strip_keys(object)
  deep_transform_keys_in_object!(object) { |key| key.sub(/^a_(\d+)_/, '') }
end

def deep_transform_keys_in_object!(object, &block)
  case object
  when Hash
    object.keys.each do |key|
      value = object.delete(key)
      object[yield(key)] = deep_transform_keys_in_object!(value, &block)
    end
    object
  when Array
    object.map! { |e| deep_transform_keys_in_object!(e, &block) }
  else
    object
  end
end