2017-02-17 28 views
0

У меня есть следующий массив хэшей, и я хочу использовать transform_keys раздеться начало каждого ключа с помощью регулярных выражений:transform_keys для массива хэшей

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

и я хочу следующее:

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

у меня есть следующий метод, но он приводит к array_of_hashes вместо transformed_hash_keys:

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

Может ли кто-нибудь сказать мне, что я делаю неправильно в этом методе?

ответ

1

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

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

Спасибо! карта будет работать лучше всего для моих целей – Munchies

1

Вот чистый раствор рубин.

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