2015-10-27 2 views
1

Цикл выполняется три раза в текстовом файле, который имеет определенные пары ключ-значение. Каждый цикл возвращает новый хэш, который напечатан ниже. Я хочу сохранить эти хэши в другой хэш. group1, group2 и group3 ключи для хэшей:Невозможно создать хэш хэш в Ruby

"group1" 
{ 
    "path"=>"/tmp/", 
    "max_hits"=>262144, 
    "min_hits"=>5240 
} 

"group2" 
{ 
    "basic_size_limit"=>262144, 
    "path"=> "/usr/bin/ruby", 
    "max_hits"=>2412, 
    "min_hits"=>871 
} 

"group3" 
{ 
    "path"=>"/usr/tmp/", 
    "basic_time_limits"=>[26214400, 26214401, 26214402], 
} 

Я инициализируется вышеуказанные хэшей в groups = Hash.new и я не хочу, чтобы хранить их в хэш хэшей. Я думал об инициализации большего хэша, например, group_of_groups = Hash.new{|hash, key| hash[key] = Hash.new}.

group_of_groups = Hash.new{|hash, key| hash[key] = Hash.new} 
Loop i in 1 .. 3 
    groups = Hash.new 
    #### 
     Do something and add to the hash groups 
    #### 
    key_name = "group" + i 
    group_of_groups[key_name] = groups 
end Loop 

Но это только дает мне {"group1"=>{}, "group2"=>{}, "group3"=>{}}

Как решить эту проблему?

+1

Неясно, какие ценности у вас уже есть. Являются ли 3 группы, как указано выше, в отдельных хешах как переменные? Пожалуйста, отредактируйте, чтобы показать больше реального кода Ruby и продемонстрировать источник этих трех хэшей (также я вижу «путь» = «/ usr/bin/ruby» 'с неправильным оператором' = 'вместо' => ') –

+0

Это три разных хэша, которые я напечатал. Я исправил ошибку '=' n '=>'. Я помещаю здесь дополнительную информацию –

+0

Я понимаю, что они 3 разных хэша, но хранятся ли они в переменных, как в массиве или иначе? –

ответ

3

Если у вас есть 3 хэшей в 3 переменных group1, group2, & group3, вы можете сделать хэш с хэшей, как это:

group1 = { 
    "path"=>"/tmp/", 
    "max_hits"=>262144, 
    "min_hits"=>5240 
} 

group2 = { 
    "basic_size_limit"=>262144, 
    "path"=> "/usr/bin/ruby", 
    "max_hits"=>2412, 
    "min_hits"=>871 
} 

group3 = { 
    "path"=>"/usr/tmp/", 
    "basic_time_limits"=>[26214400, 26214401, 26214402], 
} 

group_of_groups = {"group1"=>group1, "group2"=>group2, "group3"=>group3} 

# result 
{ 
    "group1" => { 
     "path"=>"/tmp/", 
     "max_hits"=>262144, 
     "min_hits"=>5240 
    }, 
    "group2" => { 
     "basic_size_limit"=>262144, 
     "path"=> "/usr/bin/ruby", 
     "max_hits"=>2412, 
     "min_hits"=>871 
    }, 
    "group3" => { 
     "path"=>"/usr/tmp/", 
     "basic_time_limits"=>[26214400, 26214401, 26214402], 
    }, 
} 

Имейте в виду, что все в Рубине по ссылке, так изменение хэша внутри group_of_groups также изменит исходный хеш.

+1

. Ваш ответ дал мне подсказку для решения. Я фактически очищал хэш в конце каждого цикла, в результате чего он закончился, но был удален извне, поскольку он передавался по ссылке !! –

2

Если вы хотите, чтобы инициализировать все на одном дыхании, вы могли бы написать:

group_of_groups = { 
    "group1" => { 
     "path"=>"/tmp/", 
     "max_hits"=>262144, 
     "min_hits"=>5240 
    }, 
    "group2" => { 
     "basic_size_limit"=>262144, 
     "path"=> "/usr/bin/ruby", 
     "max_hits"=>2412, 
     "min_hits"=>871 
    }, 
    "group3" => { 
     "path"=>"/usr/tmp/", 
     "basic_time_limits"=>[26214400, 26214401, 26214402], 
    } 
} 

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

0

В дополнение к другим ответам, вы также можете сделать это, если вам нужно построить хэш программно:

group1 = { 
    "path"=>"/tmp/", 
    "max_hits"=>262144, 
    "min_hits"=>5240 
} 

group2 = { 
    "basic_size_limit"=>262144, 
    "path"=> "/usr/bin/ruby", 
    "max_hits"=>2412, 
    "min_hits"=>871 
} 

group3 = { 
    "path"=>"/usr/tmp/", 
    "basic_time_limits"=>[26214400, 26214401, 26214402], 
} 

group_of_groups = 
    ["group1", "group2", "group3"].each_with_object({}) do |sub_hash_name, new_hash| 
     new_hash[sub_hash_name] = instance_eval(sub_hash_name) 
    end 

# Result 
{ 
    "group1" => { 
     "path"=>"/tmp/", 
     "max_hits"=>262144, 
     "min_hits"=>5240 
    }, 
    "group2" => { 
     "basic_size_limit"=>262144, 
     "path"=> "/usr/bin/ruby", 
     "max_hits"=>2412, 
     "min_hits"=>871 
    }, 
    "group3" => { 
     "path"=>"/usr/tmp/", 
     "basic_time_limits"=>[26214400, 26214401, 26214402], 
    }, 
} 
+1

Неправильно или целесообразно использовать eval в таком случае. – Gravatite

+0

@ Gravatite, потому что он хрупкий - если кто-то решает изменить имена локальных переменных, они могут не знать, чтобы изменить строковые значения массива? – josiah

+1

По двум причинам. Во-первых, Ruby поддерживает правильное отражение, поэтому нет смысла использовать eval для получения переменной. Во-вторых, это более философская проблема в том, что eval часто приводит к множеству зол от уязвимостей безопасности, что затрудняет диагностику ошибок и всех других проблем. Быстрый поиск в Google должен включать более подробные статьи, когда целесообразно использовать eval. – Gravatite

Смежные вопросы