2014-08-19 5 views
0

У меня есть хэш, как это:Как изменить хэш-ключи

test 
=> {"QTC-1 test"=>"pass", "QTC-2 test"=>"fail"} 

Я хочу взять каждый ключ в хэш и удалить все символы после цифр, пример:

«QTC-1 тест "должен быть равен„QTc-1“

Я близок к решению, но не полностью там:

str = test.keys[0] 
=> "QTC-1 test" 

new = str.slice(0..(str.index(/\d/))) 
=> "QTC-1" 

но нужны некоторые он lp делает это с помощью хеш-ключа (ов).

Бонус

Изменение значений в соответствующие числовые значения:

Таким образом, если значение = передать затем изменить его на 1 или если значение = сбой, то изменить его на 2.

бонус возможного ответ:

scenarios.each_pair { |k, v| 

    case v 
    when 'pass' 
    scenarios[k] = 1 
    when 'fail' 
    scenarios[k] = 2 
    when 'block' 
    scenarios[k] = 3 
    else 
    scenarios[k] = 4 
    end 

    } 
+0

Вы не можете измените ключи, но вы можете вставить те же значения под новыми клавишами (и удалить старые ключи) или создать новый хеш с правильными клавишами. –

ответ

2

Этот ответ изменяет исходный хеш, а не создает новый.

h = {"QTC-1 test"=>"pass", "QTC-2 test"=>"fail"} 
h.keys.each{|k| h[k[/.*\d+/]] = h.delete(k)} 
h #=> {"QTC-1"=>"pass", "QTC-2"=>"fail"} 
+1

Спасибо за быстрый ответ, это сработало! – Farooq

1
new_hash = {} 
old_hash = {"QTC-1 test"=>"pass", "QTC-2 test"=>"fail"} 
old_hash.map{|key, value| new_hash[key.split(" ").first]=value} 

p new_hash 
+0

Спасибо за быстрый ответ! – Farooq

1
h = {"QTC-1 test"=>"pass", "QTC-2 test"=>"fail"} 
Hash[h.map { |k,v| [k.sub(/(?<=\d).*/, ''), v] }] 
# => {"QTC-1"=>"pass", "QTC-2"=>"fail"} 
+0

Спасибо за быстрый ответ! – Farooq

3

С Руби 2.1.2:

test = {"QTC-1 test"=>"pass", "QTC-2 test"=>"fail"} 
(test.keys.map { |k| k.sub /\stest\z/, '' }.zip test.values).to_h 
#=> {"QTC-1"=>"pass", "QTC-2"=>"fail"} 

Идея заключается в том, что вы удаляете строку «тест» из каждого ключа, пронестись вместе со значениями из исходного хэша, а затем включите результирующий массив обратно в хэш.

+0

Спасибо за быстрый ответ! – Farooq

1

Для бонусной части:

Для обновления от «проход» или «провал» на номер значения на вашем недавно пересмотренным хэша, вы можете использовать #each_pair с условным. Формат ternary operator используется здесь:

test = {"QTC-1 test"=>"pass", "QTC-2 test"=>"fail"} 
test.each_pair { |k, v| v == "pass" ? test[k] = 1 : test[k] = 2 } 
# => {"QTC-1 test"=>1, "QTC-2 test"=>2} 

Обновление для ситуации, когда есть больше возможностей, чем «пройти» и «провал» ... Вы можете использовать case заявление:

test = 
    { 
    "QTC-1 test" => "pass", 
    "QTC-2 test" => "fail", 
    "QTC-3 test" => "blocked", 
    "QTC-4 test" => "denied", 
    "QTC-5 test" => "other", 
    "QTC-6 test" => "error" 
    } 

test.each_pair do |k, v| 
    case v 
    when "pass" 
    test[k] = 1 
    when "fail" 
    test[k] = 2 
    when "blocked" 
    test[k] = 3 
    when "denied" 
    test[k] = 4 
    when "other" 
    test[k] = 5 
    else 
    test[k] = "well dangit, I don't know what to do with #{v}" 
    end 
end 

p test 

=> {"QTC-1 test"=>1, 
    "QTC-2 test"=>2, 
    "QTC-3 test"=>3, 
    "QTC-4 test"=>4, 
    "QTC-5 test"=>5, 
    "QTC-6 test"=>"well dangit, I don't know what to do with error"} 
+0

Спасибо, Да, что, если у меня есть более двух вариантов? Например: 1 = pass, 2 = fail, 3 = заблокирован и т. Д. – Farooq

+0

Я думаю, что-то вроде этого может работать: сценарии.each_pair {| k, v | дело против когда 'проход' сценарии [K] = 1 , когда 'сбой' сценарии [K] = 2 , когда 'блок' сценарии [K] = 3 еще сценарии [K] = 4 конец } Отредактировано первое сообщение для удобства чтения. – Farooq

+1

Yep @Farooq вы прибивали его, я думаю, что инструкция 'case' - хорошая техника здесь –

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