2015-11-05 3 views
1

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

array = [ "Name = abc", "Id = 123", "Interest = Rock Climbing" ] 

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

hash = { "Name" => "abc", "Id" => "123", "Interest" => "Rock Climbing" } 

я должен делать что-то неправильно, потому что я получаю странные сопоставления с моим .shift.split в результате { "Name = ABC" => "Id = 123"}. Благодарю.

ответ

4

Все, что вам нужно сделать, это разделить каждую часть массива в ключ и значение (дающим массив из двух элементов массива), а затем передать результат в удобные Hash[] метод:

arr = [ "Name = abc", "Id = 123", "Interest = Rock Climbing" ] 

keys_values = arr.map {|item| item.split /\s*=\s*/ } 
# => [ [ "Name", "abc" ], 
#  [ "Id", "123" ], 
#  [ "Interest", "Rock Climbing" ] ] 

hsh = Hash[keys_values] 
# => { "Name" => "abc", 
#  "Id" => "123", 
#  "Interest" => "Rock Climbing" } 
1

Вы можете сделать это следующим образом (с помощью Enumerable#each_with_object):

array.each_with_object({}) do |a, hash| 
    key,value = a.split(/\s*=\s*/) # splitting the array items into key and value 
    hash[key] = value # storing key => value pairs in the hash 
end 
# => {"Name"=>"abc", "Id"=>"123", "Interest"=>"Rock Climbing"} 

Если вам немного трудно понять each_with_object, вы можете сделать это в наивно (Только накапливая key и value с в result_hash):

result_hash = {} 
array.each do |a| 
    key,value = a.split(/\s*=\s*/) # splitting the array items into key and value 
    result_hash[key] = value # storing key => value pairs in the result_hash 
end 
result_hash 
# => {"Name"=>"abc", "Id"=>"123", "Interest"=>"Rock Climbing"} 
+1

Это лучший ответ. – Charles

0
array.each_with_object({}) { |s,h| h.update([s.split(/\s*=\s*/)].to_h) } 
    #=> {"Name"=>"abc", "Id"=>"123", "Interest"=>"Rock Climbing"} 

Для версий Ruby, до 2,0 (при Array#to_h была введена) заменить [s.split(/\s*=\s*/)].h с Hash[[s.split(/\s*=\s*/)]]. шагов:

enum = array.each_with_object({}) 
    #=> #<Enumerator: ["Name = abc", "Id = 123", 
    #  "Interest = Rock Climbing"]:each_with_object({})> 

Мы можем увидеть элементы этого интервьюер путем преобразования его в массив:

enum.to_a 
    #=> [["Name = abc", {}], ["Id = 123", {}], ["Interest = Rock Climbing", {}]] 

Первый элемент enum передается в блок, блок переменных назначаются:

s,h = enum.next 
    #=> ["Name = abc", {}] 
s #=> "Name = abc" 
h #=> {} 

и расчет выполняется блок:

h.update([s.split(/\s*=\s*/)].to_h) 
    #=> h.update([["Name", "abc"]].to_h) 
    # {}.update({"Name"=>"abc"}) 
    # {"Name"=>"abc"} 

, который является обновленным значением h.

Следующий элемент enum передается в блоке:

s,h = enum.next 
    #=> ["Id = 123", {"Name"=>"abc"}] 
s #=> "Id = 123" 
h #=> {"Name"=>"abc"} 

h.update([s.split(/\s*=\s*/)].to_h) 
    #=> {"Name"=>"abc", "Id"=>"123"} 

и так далее.

0

Попробуйте

array.map {|s| s.split('=')}.to_h 

=> {"Name "=>" abc", "Id "=>" 123", "Interest "=>" Rock Climbing"} 
Смежные вопросы